magento2: XML syntax to change block's template

Summary

Documentation claims that it is possible to change a block’s template by the following layout update:

<referenceBlock name="navigation.sections">
  <arguments>
    <argument name="template" xsi:type="string">Magento_Theme::html/nav_sections.phtml</argument>
  </arguments>
</referenceBlock>

But It doesn’t work.

Using action node, instead of arguments node, works fine:

<referenceBlock name="navigation.sections">
  <action method="setTemplate">
    <argument name="template" xsi:type="string">Magento_Theme::html/nav_sections.phtml</argument>
  </action>
</referenceBlock>

Source: http://devdocs.magento.com/guides/v2.0/frontend-dev-guide/layouts/xml-manage.html#set_template

Preconditions (*)

  1. Magento 2.3-develop
  2. PHP 7.2

Steps to reproduce (*)

Try to change a block’s template by the following layout update e.g.: 3356

Expected result (*)

Block’s template is changed without any errors

Actual result (*)

Got exception 3356ex

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 18
  • Comments: 21 (9 by maintainers)

Commits related to this issue

Most upvoted comments

The reason why it doesn’t work is because the method \Magento\Framework\View\Layout\Generator\Block::generateBlock:

When we want to overwrite an existing block, this one was at first initialized via a layout XML with an attribute template.

Into the generateBlockmethod, arguments are passed to the block, then setTemplate is called and then in the calling method process the action is called.

So the priority is the following:

  • actions
  • setTemplate via attribute template
  • arguments

When a block was initialized with its attribute template, arguments will have no effect. That’s why you need to use actions

protected function generateBlock(
        Layout\ScheduledStructure $scheduledStructure,
        Layout\Data\Structure $structure,
        $elementName
    ) {
        list(, $data) = $scheduledStructure->getElement($elementName);
        $attributes = $data['attributes'];

        if (!empty($attributes['group'])) {
            $structure->addToParentGroup($elementName, $attributes['group']);
        }
        if (!empty($attributes['display'])) {
            $structure->setAttribute($elementName, 'display', $attributes['display']);
        }

        // create block
        $className = $attributes['class'];
        $block = $this->createBlock($className, $elementName, [
            'data' => $this->evaluateArguments($data['arguments'])
        ]);
        if (!empty($attributes['template'])) {
            $block->setTemplate($attributes['template']);
        }
        if (!empty($attributes['ttl'])) {
            $ttl = (int)$attributes['ttl'];
            $block->setTtl($ttl);
        }
        return $block;
    }

@magento-engcom-team the PR you’ve referencing was also closed, as it required some changes in the pull request code. So now both this issue and PR are closed but the issue still exists and documentation is still wrong. In my opinion this issue should stay open until it’s fixed.

If you consider this a feature request, please at last fix the documentation.

This issue still exist.

<referenceBlock name="product.info.addtocart"> <arguments> <argument name="template" xsi:type="string">Yoma_Dipen::addtocart.phtml</argument> </arguments> </referenceBlock>

I tried this code in my customer module’s catalog_product_view.xml

it’s not working.

Closing the issue as the feature request. Please, see more details here https://github.com/magento/magento2/pull/8913#discussion_r106549969

This issue still exists. We should reopen it.

Doesn’t work in 2.3.3-p1

FYI This issue was resolved by adjusting the docs and highlighting the applied priorities in https://github.com/magento/devdocs/pull/7977

In 2.1.0 I still have to use ‘action’ and the online documentation is still wrong.