XML syntax to change block's template #3356

Open
cescopag opened this Issue Feb 10, 2016 · 7 comments

Projects

None yet

10 participants

@cescopag

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>

What's the right way to customize a template?

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

@shiftedreality
Member

Hi @cescopag

You provided correct way with action method
Looks like mistake in public docs

@almarchenko

Hi @cescopag!
Thank you for reporting this. Looks like there's a bug in magento code, that is why the code sample provided in docs doesn't work. But you found the correct temporary solution.
It must be temporarily as is deprecated. I'll add a note in docs, and updated them when the bug is fixed.

@LiamFielding

Is this now fixed?

@dnadle
dnadle commented Aug 23, 2016 edited

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

@LiamFielding

@digitalpianism No, sorry - I believe that's what we all tried first. At least I did, that's how I ended up here.

@digitalpianism
Contributor

@LiamFielding my bad. I guess we gotta wait ^^

@vzabaznov vzabaznov self-assigned this Oct 4, 2016
@diglin
Contributor
diglin commented Nov 2, 2016 edited

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;
    }
@veloraven veloraven added bug report Frontend and removed DOC labels Dec 22, 2016
@vzabaznov vzabaznov was unassigned by veloraven Dec 22, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment