In Magento 1, it was pretty common to write a bit of layout update XML that looked like the following.
<reference name="head">
<action method="setLabel">
<label>skin_js</label>
</action>
</reference>
This XML translates roughly into the following PHP pseudo code
$block = $layout->getBlock('head');
$block->setLabel('skin_js');
Or, in plain english, Magento fetches a reference to the already instantiated block object named head
, and then calls this block’s setLabel
method.
This syntax has survived, mostly, into the Magento 2 era. Although the Magento provided “dev docs” say the syntax is “not recommended“, action methods still work
<referenceBlock name="catalog-search-advanced-link">
<action method="setLabel">
<argument name="value" xsi:type="string">Does this Work</argument>
</action>
</referenceBlock>
The names have changed a bit — the outer tag is a better named <referenceBlock/>
, and the arguments are now an actual <argument name="..."/>
node that requires an xsi:type
— but the same intent and semantics from M2 are intact.
What’s odd about this is — you can also use <referenceBlock/>
to override <argument/>
values. The follow code works
<referenceBlock name="catalog-search-advanced-link">
<arguments>
<argument name="label" xsi:type="string" translate="true">Changing the Label</argument>
</arguments>
</referenceBlock>
This will change the initial value of the label
property of the catalog-search-advanced-link
block (the <arguments/>
node got their name because they set the value of the $data
argument passed into the block’s __construct
method). While useful, this syntax is odd because the semantics of <reference/>
nodes have always been
Get a reference to the already instantiated block object named
catalog-search-advanced-link
However, in the <arguments/>
case, you’re putting something inside a <referenceBlock/>
node that has an impact on the block before it’s instantiated. Having argument nodes here breaks the standard metaphors of the Layout DSL and makes it harder to reason about, and harder to teach to folks new to the platform. Also, with the reference metaphor broken, it’s not clear how different modules trying to set arguments on the same block will resolve their differences. Is it just an extra merge with the original <block/>
? Or is there more custom logic at play?
I recall early in Magento 2’s development cycle an architect mentioned the changes and recommendations for the Layout DSL were an attempt to make the language more declarative (vs. imperative). A declarative layout DSL would have been a pretty neat thing. Unfortunately, a declarative feature or two sitting along side mostly imperative code only serves to confuse things, and make the technical moat around access to Magento development larger, not smaller.