61

In Magento 1, as a module developer it's possible to change a block's template using layout XML code something like this

<reference name="block_to_change">
 <action method="setTemplate">
 <param>/path/to/template.phtml</param>
 </action>
</reference>

and then adding your template to the base theme.

app/design/frontend/base/default/template/path/to/template.phtml

Is it possible, as a module developer, to do something similar in Magento 2? Or would I need to use layout XML or PHP code to remove the block I'm interested in, and insert a new block with a different template (whose class extends the original block class's)

I know I could create a custom theme that replaces a template, but I'm interested in creating a module that changes the default template, but still allows a custom theme to then replace that template.

asked Oct 12, 2015 at 15:45

6 Answers 6

84

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>
answered Oct 12, 2015 at 15:52
4
  • Can you explain the steps how can i change the layout, Actually i want to update the add to addtocart.phtml file according to system configuration and also want to update this using custom module Commented Nov 25, 2015 at 7:44
  • 5
    KAndy solution didn't work for me but this one yes Commented Jan 26, 2016 at 16:09
  • I have changed the template of the block name "customer_account_dashboard_top"<body> <referenceBlock name="customer_account_dashboard_top"> <action method="setTemplate"> <argument name="template" xsi:type="string">Namespace_Modulename::order/recentorder.phtml</argument> </action> </referenceBlock> </body>" but its not getting work, kindly check and let me know your comments Commented Apr 26, 2018 at 17:36
  • action is now deprecated. Commented Aug 7, 2020 at 9:08
52

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>
answered Oct 12, 2015 at 18:03
9
  • Can you explain the steps how can i change the layout, Actually i want to update the add to addtocart.phtml file according to system configuration and also want to update this using custom module Commented Nov 25, 2015 at 7:44
  • @KAndy would you mind clarifying where the statement "action node is deprecated is coming from" - after a quick search of the current core code base I found 4 uses with referenceBlock changing the template . All 4 of them use the action node to set a template and none this approach. Commented Mar 9, 2016 at 10:18
  • 4
    Thanks - I'll just leave a reference to a bug report here github.com/magento/magento2/issues/3356 - the method posted in this answer, while possibly the future way of doing things, does not yet work as advertised Commented Mar 21, 2016 at 10:27
  • 2
    @KAndy Is your code example 100% correct? I tried that and I can't get it to work in any way. The other answer from @Mage2.PRO (which uses <action method='setTemplate'>) works without problems. Commented May 24, 2016 at 8:52
  • 2
    This doesn't work. Accepted answer does though. Commented Aug 20, 2017 at 22:20
37

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> 
nikin
1,1529 silver badges19 bronze badges
answered Jun 28, 2016 at 12:32
19

The following worked for me in Magento EE 2.2.3

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
 <body>
 <referenceBlock name="core.module.block.name" template="[Vendor]_[Module]::path/to/your/template.phtml" />
 </body>
</page>

Note: if you are using a custom module to change a core's template and you are going mad because the previous code snipped does not work, make sure your module is loaded after the core module you are trying to change (module.xml) and you executed bin/magento setup:upgrade :)

answered May 25, 2018 at 15:52
1
  • This is the cleanest way in my opinion. Commented May 25, 2018 at 16:02
8

I don't know why, but i find this way to be the best:

<referenceBlock name="sales.order.items.renderers.default" template="Foo_Bar::sales/order/items/renderer/default.phtml"/>
answered Mar 21, 2018 at 13:43
0
0
<referenceBlock name="sales.order.items.renderers.default" template="Foo_Bar::sales/order/items/renderer/default.phtml"/>

This will work only if your block wasn't overwritten before using setTemplate method. Magento 2.2.x and higher.

answered Sep 25, 2018 at 7:00
1
  • 1
    This is exactly the same piece of code as Aivoris’ answer above. Commented Mar 26, 2021 at 15:11

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.