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:
<cms_index_index>
<reference name="root">
<block type="core/template" name="example_block" as="exampleBlock" template="page/html/example-block.phtml"/>
</reference>
</cms_index_index>
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') ?>
...to 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"/>
</reference>
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"/>
</reference>
Nothing appears...
<reference name="root">
<block type="core/template" name="example_block" after="header" template="page/html/example-block.phtml"/>
</reference>
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 1.7.0.2 (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:
core/text_list
block getChildHtml
without any parametersWhen 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 theroot
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.