Magento 2: Changing a Block's Template
Of course, it is possible:
<referenceBlock name="copyright">
<action method="setTemplate">
<argument name="template" xsi:type="string">Dfr_Backend::page/copyright.phtml</argument>
</action>
</referenceBlock>
Action node is deprecated, but you can use block arguments
<referenceBlock name="block_to_change">
<arguments>
<argument name="template" xsi:type="string">[Vendor]_[Module]::/path/to/template.phtml</argument>
</arguments>
</referenceBlock>
To understand the difference between <arguments>
and <action>
you must understand how the constructors of Magento 2 objects work. If you override a constructor in Magento, you'll always get a $data-parameter
which is an array. This is the data as provided in the XML files and translated to the internal $_data-array
of \Magento\Framework\DataObject
:
<referenceBlock name="catalog.topnav">
<arguments>
<argument name="template" xsi:type="string">Foo_Bar::buzz.phtml</argument>
</arguments>
</referenceBlock>
...
public function __construct(array $data = [])
{
// $_data is populated with the arguments from XML:
// so $_data['template'] is now 'Foo_Bar::buzz.phtml'
$this->_data = $data;
}
However, in the case of a template, if setTemplate()
is used in the pseudo constructor (_construct()
, single underscore), this means that the $data
is overridden, no matter if it's set in the XML.
public function _construct()
{
$this->setTemplate('foo/bar.phtml');
}
In that scenario, <action>
is prefered, since this is executed after the constructor & pseudo constructor.
<referenceBlock name="catalog.topnav">
<action method="setTemplate">
<argument name="template" xsi:type="string">Foo_Bar::buzz.phtml</argument>
</action>
</referenceBlock>