Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

xml

magento

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...

like image 687
mike-source Avatar asked Jan 23 '13 16:01

mike-source


People also ask

How does Magento 2 XML work?

In Magento 2, layout XML files are used to describe the structure of the pages. Developers most commonly have to solve two basic types of tasks: modification of the existing layout files and the creation of their own. Let's take a closer look at these types of tasks.

How do you call CMS block in Magento 2 using layout XML?

Except for displaying CMS block on CMS Page or CMS Block, showing it on category page there is an option to call CMS block programmatically using XML file. You need to replace "my_cmsblock_identifier" with your CMS block Identifier or ID (we recommend to use Identifier).

How do I move a block in XML in Magento 2?

For moving a block to another destination, we need to use the <move> tag with a specific element name and destination place. <move> Tag will set the declared block or container element as a child of another element in the specified order.


1 Answers

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.

like image 195
Alan Storm Avatar answered Sep 29 '22 11:09

Alan Storm