Magento – Action elements and helpers in layout

This is relevant for Magento 1.4.1.1.

I have been unable to find any decent documentation on how Magento handles the <action method=”…”> element and helpers within the arguments. After some debugging I found the method responsible for handling these elements. Take a look at app/code/core/Mage/Core/Model/Layout.php on line 289 at the _generateAction method. This method takes the <action> element as $node. It loops through all the child nodes (what would be the method arguments) and turns them into an associative array. If any child node has the “helper” attribute specified it will use that helper to get the value. You can pass arguments to the helper method with further child nodes. This is better illustrated through an example:

<reference name="breadcrumbs">
    <action method="addLink">
        <label>New Link</label>
        <url helper="core/url/getUrl"><page>new-page</page></url>
    </action>
</reference>

This has the effect of making the following calls:

Mage_Page_Block_Html_Breadcrumbs::addLink(
    'Add Link',
    Mage_Core_Helper_Url::getUrl('new-page')
);

The above is merely an example the addLink and getUrl methods do not exist. As far as I’ve found there’s no way to get a generic URL through any helper. In addition the element names for the arguments are only by convention. They are passed in order and the names do not matter.

So in summary:

  • The <action> element calls the “method” attribute on the parent block’s class. Mage_Page_Block_Html_Breadcrumbs::addLink.
  • The child elements are passed as arguments in order. <label> and <url>.
  • Any child elements specifying the “helper” attribute will use that class and method to determine their value. Mage_Core_Helper_Url::getUrl.
  • Any child elements of an element specifying the “helper”attribute will be passed as arguments to the helper method. <page>.

Unfortunately you cannot use helper methods any further down the chain. For example a call to the addCrumb method might look like this:

<reference name="breadcrumbs">
    <action method="addCrumb">
        <crumbName>newlink</crumbName>
        <crumbInfo>
            <label>New Link</label>
            <link>new-link</link>
        </crumbInfo>
    </action>
</reference>

The crumbInfo argument is an associative array. While Magento will construct the array correctly you cannot use a helper on the <link> element where it would be quite useful.

Magento – Add new layout

This is the first in a, hopefully, useful series of quick how-tos for Magento. All of them will be referencing Magento 1.4.1.1.

To add a new layout to Magento that is available in the CMS you’ll need to edit

app/etc/local.xml

To insert the <page> element like:

<config>
    <global>
        <page>
            <layouts>
                <three_box module="page" translate="label">
                    <label>3 box</label>
                    <template>page/3box.phtml</template>
                    <layout_handle>page_three_box</layout_handle>
                </three_box>
            </layouts>
        </page>
    </global>
</config>

To make the layout default you can also add

<is_default>1</is_default>

The layout can now be selected in the CMS as “3 box”. It will use the page/3box.phtml to render in whatever theme you are using. For example:

app/design/frontend/base/default/my_theme/template/page/3box.phtml

To reference the new layout in your layout XML files you use the <layout_handle> value. In our example, <page_three_box>.