Magento 1.9 – Layout local.xml vs Module Layout

ce-1.9.0.1layout

I've recently started using the local.xml as my playground for layouts. Before I had my doubts using it because of…reasons.
I got to see it's advantages, but I hit a brick wall now.
In the default catalog.xml layout file there is a certain block (name not important). Using the layout.xml I added a generic child block to it where I want to place other blocks.

<reference name="not.important">
    <block type="core/text_list" name="extra.left.menu" as="extra" />
</reference>

So far so good.
But now, I have one extension that should add child block to the one declared above.
If I add this new block using local.xml it works nicely.

<block type="core/text_list" name="extra.left.menu" as="extra">
    <block type="myextension/some_block" template="some/template.phtml" as="some_name" name="some_name" />
</block>

But I don't want to do it via local.xml because this new extension might be disabled in the future. If I do it via local.xml and disable the extension it will flood my log files because the block does not exist anymore.
So in my extension layout file I add this:

<reference name="extra.left.menu">
    <block type="myextension/some_block" template="some/template.phtml" as="some_name" name="some_name" />
</reference>

But This way it does not work. I feel this happens because the local.xml file is loaded last, and I cannot add a module dependency so my extension layout file would be loaded after layout.xml.
How should I tackle this? Did I get something wrong?
Or if I want it like this I have to use the "good old way" of cloning catalog.xml in my theme and adding this new block in the catalog.xml of my theme?

Best Answer

When rendering the layout in Magento a few steps happen:

  1. Handles are defined (default, catalog_product_view, etc.)
  2. All XML files are loaded and merged to a single huge XML file, that file is stored somewhere in the cache.
  3. The contents of all handles are loaded and merged into one page-xml file.
  4. The order where the XML files are loaded are alphabetically and the local.xml is loaded last (there are also database layout updates which are loaded even later. (source https://github.com/OpenMage/magento-mirror/blob/magento-1.9/app/code/core/Mage/Core/Model/Layout/Update.php#L433-L438)
  5. Finally the XML is parsed and the blocks is initiated.

So why isn't your example working? This is because the module XML file is loaded before the local.xml file. What happens is that the system first tries to add a block to a reference (to a block) which doesn't exist yet.

To solve te issue: You can use an update, updates get placed before the handles they are called in.

<default>
    <update handle="awesome_new_container_handle"/>
</default>

<awesome_new_container_handle>
    <reference name="not.important">
        <block type="core/text_list" name="extra.left.menu" as="extra" />
    </reference>
</awesome_new_container_handle>

And in your other module file add the block like your did.

<default>
    <reference name="extra.left.menu">
        <block type="myextension/some_block" template="some/template.phtml" as="some_name" name="some_name" />
    </reference>
</default>
Related Topic