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

I'm a front-end Magento dev, have built quite a few of my own themes and I want to understand Magento's XML block positioning better...

I normally use a local.xml file to manipulate everything, I can define a block as follows:

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

This would create a block on the home page (cms_index_index) and since the block is created one level under 'root', I would normally call the block by adding:

<?php echo $this->getChildHtml('exampleBlock') ?> 1column.phtml (or 2columns-left/right.phtml, 3columns.phtml etc). The block can be placed on any page by substituting 'cms_index_index' for the appropriate page tag.

I see stuff like the following throughout the core XML files, and in tutorials:

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

'content' is a block which is part of magento's general page structure and, from what I understand, before="content" should place it where you'd expect, without needing to use getChildHtml('exampleBlock'), so far so good... however, before/after hardly ever seems to work for me, and I frequently find myself resorting to the getChildHtml method as backup, which isn't always ideal, and means editing more .phtml files than necessary.

I've tried:

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

Nothing appears...

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

Still nothing.... I'm also aware of using before="-" or after="-" to place something before everything within it's parent block. I occasionally have some luck with that, but generally just get confused and frustrated.

I've googled all over the place for 'magento xml before/after not working' and beginning to wonder if its just me this happens to... can anyone explain when I can and can't use before/after to position blocks? What's wrong with the above examples?

I'm in magento (latest available at time of posting)

The main motivation for this is to reduce the number of core .phtml files I need to edit just to add a getChildHtml(), so if there is another (XML) way to get around this I'd be interested to know...


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"/>

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.

Need Your Help

How to remove the value from this NSDictionary?

ios nsdictionary

Hello everyone i have a dictionary value when i nslog returns the following below :

JQuery: Insert HTML into corresponding selectors using custom .load()

javascript jquery html load find

To help demostrate what I am after, consider the following jsfiddle:

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.