Magento XML using before/after to place blocks hardly ever works Magento XML using before/after to place blocks hardly ever works xml xml

Magento XML using before/after to place blocks hardly ever works


The before and after attributes only work in one of two cases:

  1. When you insert into a core/text_list block
  2. When your template block calls getChildHtml without any parameters

When you say

<reference name="root">   <block type="core/template" name="example_block" before="content" template="page/html/example-block.phtml"/></reference>

you're telling Magento

Hey Magento, put the example_block inside the root block.

When you put a number of different blocks inside a parent, those blocks have an implicit order. For template blocks, this order doesn't matter, since those blocks are being explicitly rendered.

<?php echo $this->getChildHtml('example_block') ?>

However, there's two cases where order matters. First, if you call

<?php echo $this->getChildHtml() ?>

from a template, then Magento will render all the child blocks, in order.

Secondly, there's a special type of block called a "text list" (core/text_list/Mage_Core_Block_Text_List). These blocks render all their children automatically, again in order. The content block is an example of this

<block type="core/text_list" name="content"/>

That's why you can insert blocks into content and they render automatically.

So, in your example above, you're inserting blocks into the root block. The root block is a template block whose phtml template uses getChildHtml calls with explicit parameters. Therefore the before and after attributes don't do what you (and many others, including me) wish they did.


I wonder but it seems that Mage_Core_Block_Abstract:

public function getChildHtml($name = '', $useCache = true, $sorted = false)

doesn't render the blocks in order because of $sorted = false.

So finally the order/sorting of blocks is by default only considered in Core/Block/Text/List - Block.

If you want to ensure that child blocks were output in correct order you have to use:

<?php echo $this->getChildHtml('', true, true) ?>