Layout merging is part of the page rendering process in Magento, that is why I suggest taking a look at this process for a better understanding of Magento 2 in general.
The process of layout merging
First, Magento combines all layout XML files into one large XML document using the “_loadFileLayoutUpdatesXml” method. After that, it uses the “_fetchPackageLayoutUpdates” method to find all the layout instructions for specific handles, merges all of them together and we get the final XML document as a result. Magento bypasses this document by creating PHP classes for each block. After that, the result is rendered for a specific page, forming an HTML tree of the page by adding CSS styles and JavaScript files.
The next thing you should know about layout merging is that layout is merged in a strict order. This order is determined by the module’s load order (go to devdocs.magento.com to learn how to change the module’s load order). You can check out the current module’s load order in the app/etc/config.php file. If there are two or more conflicting instructions from different modules in the layout files during merging, then the one whose module is loaded last will win and be used.
Speaking about layout merging, it will be useful to recall extending and overriding layout files. When we create an extending layout file, it will complement the file that it has extended, and if the extending file we created contains instructions that contradict the instructions of the original file, they will override them during the layout merging. For example, if in the original layout file contains the following instruction:
<move element=”form.subscribe” destination=”footer_row” after=”footer_column_4″/>
and the extending theme file contains this instruction:
<move element=”form.subscribe” destination=”footer_row” after=”footer_column_5″/>
the form.subscribe element will eventually move to the footer_row element after the footer_column_5 and not after footer_column_4.
If we use overriding layout files, then the original file that we have overridden does not participate in layout merging at all. But you should use overriding extremely carefully, since this may cause problems when updating Magento (for more details, see my article Overriding Layout Files in Magento 2 on our blog)
It may be unclear how the merged XML document will eventually look like. You can use the following method to see the result of a layout merging:
- go to the magento\framework\View\Result\Page.php file;
- find the $output = $this->renderPage() line in the render() method;
- after this line add the following command: $output .= $this->getLayout()->getXmlString().
After that, go to the front end of the site and in the browser’s developer tools on the Source tab find the final XML for this page (after the <html> tag).
How design areas influence merging
After the request for the current page is received (it can be a front end or an admin panel page) Magento first merges layout files into the base area and then into the area that applies to the current request (frontend or adminhtml respectively).
For greater clarity, I suggest taking a look at the general layout merging order:
- Basic module files are loaded.
- The request area module files are loaded (frontend or adminhtml).
- The files are sorted according to the priority of the modules (the module’s load order is described above).
- Theme files are loaded (the files of basic, parent and current themes). The younger the theme, the higher priority is given to the instructions in the extending and overriding layout files. The current theme has the highest priority.
How merging can remove the elements added earlier
In order to remove a previously added element, there is a remove attribute for the referenceBlock and referenceContainer tags, respectively.
Here is how it looks like:
<referenceBlock name=”breadcrumbs” remove=”true”/>
and
<referenceContainer name=”header.container” remove=”true”/>
What are additive changes and overriding changes in the layout merging
When we complement the existing XML elements with new ones (e.g., we add new arguments for an existing element), these will be additive changes. And when we replace something in the existing elements (for example, we change the current value of an argument with our own), these are overriding changes.
Here is an example of additive changes.
Let’s say we have a register-link block that has a label attribute with the Create an Account value:
1 2 3 4 5 6 7 |
<block class="Magento\Customer\Block\Account\RegisterLink" name="register-link"> <arguments> <argument name="label" xsi:type="string" translate="true"> Create an Account </argument> </arguments> </block> |
In order to add a new test-argument argument for the register-link block you should write the following code in your existing layout file:
1 2 3 4 5 6 7 |
<referenceBlock name="register-link"> <arguments> <argument name="test-argunemt" xsi:type="string" translate="true"> Value Test Argument </argument> </arguments> </referenceBlock> |
And here is an example of overriding changes. In order to change the existing label argument for the register-link block, you should write the following code in your existing layout file:
1 2 3 4 5 6 7 |
<referenceBlock name="register-link"> <arguments> <argument name="label" xsi:type="string" translate="true"> New label value </argument> </arguments> </referenceBlock> |
That was a detailed outlook on layout merging in Magento 2, hope everything makes sense. Please leave your comments and questions in the section below and I will answer them ASAP.