Magento – Custom page layout handle

layoutlayout-update

Not very experienced with Magento layouts, so forgive me, if the question is too vague.

I have defined a layout in config.xml similar to this:

 <page>
    <layouts>
        <campaign module="page" translate="label">
            <label>Campaign</label>
            <template>page/campaign.phtml</template>
            <layout_handle>campaign</layout_handle>
        </campaign>
    </layouts>
</page>

But I seem not the get the <layout_handle> definition correct, have tried define a separate file, using another handle, etc. Nothing seems to work, the default layout for the page (category) is always used.

Edit: the code is in module's config.xml. I wish to use my own layout instead of the catalog_category_default

Best Answer

Layout handle, defined in Page Layout, for some reason, works only for CMS pages (Alan Storm described it here). If you want add custom handle to specified categories, you could use this code:

app/etc/modules/SeStro_CatalogPageLayoutHandle.xml

<?xml version="1.0" encoding="UTF-8" ?>
<config>
    <modules>
        <SeStro_CatalogPageLayoutHandle>
            <active>true</active>
            <codePool>local</codePool>
        </SeStro_CatalogPageLayoutHandle>
    </modules>
</config>

app/code/local/SeStro/CatalogPageLayoutHandle/etc/config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<config>
    <modules>
        <SeStro_CatalogPageLayoutHandle>
            <version>0.1.0</version>
        </SeStro_CatalogPageLayoutHandle>
    </modules>

    <global>
        <resources>
            <sestro_catalogpagelayouthandle_setup>
                <setup>
                    <module>SeStro_CatalogPageLayoutHandle</module>
                    <class>Mage_Catalog_Model_Resource_Setup</class>
                </setup>
            </sestro_catalogpagelayouthandle_setup>
        </resources>

        <events>
            <controller_action_layout_load_before>
                <observers>
                    <addCategoryLayoutHandle>
                        <class>SeStro_CatalogPageLayoutHandle_Model_Observer</class>
                        <method>addCategoryLayoutHandle</method>
                    </addCategoryLayoutHandle>
                </observers>
            </controller_action_layout_load_before>
        </events>

        <page>
            <layouts>
                <bazinga>
                    <label>Bazinga</label>
                    <template>page/1column.phtml</template>
                    <layout_handle>bazinga</layout_handle>
                </bazinga>
            </layouts>
        </page>
    </global>
</config>

app/code/local/SeStro/CatalogPageLayoutHandle/Model/Observer.php

<?php
class SeStro_CatalogPageLayoutHandle_Model_Observer
{

    public function addCategoryLayoutHandle(Varien_Event_Observer $observer)
    {
        $category = Mage::registry('current_category');

        if (!($category instanceof Mage_Catalog_Model_Category)) {
            return;
        }

        if ($category->getLayoutHandle()) {
            $layoutHandleName = str_replace(' ', '_', $category->getLayoutHandle());
            $update = $observer->getEvent()->getLayout()->getUpdate();
            $handles = $update->getHandles();
            $update->resetHandles();

            foreach ($handles as $handle) {
                $update->addHandle($handle);
                if (trim($handle) === 'catalog_category_layered') {;
                    $update->addHandle($layoutHandleName);
                }
            }
        }
    }
}

app/code/local/SeStro/CatalogPageLayoutHandle/sql/catalogpagelayouthandle_setup/install-0.1.0.php

<?php

$installer = $this;
$installer->startSetup();

$installer->addAttribute(Mage_Catalog_Model_Category::ENTITY, 'layout_handle', array(
    'group'             => 'Custom Design',
    'input'             => 'text',
    'type'              => 'text',
    'frontend_class'    => 'validate-alphanum-with-spaces',
    'label'             => 'Layout Handle',
    'backend'           => '',
    'visible'           => true,
    'required'          => false,
    'global'            => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
));

$installer->endSetup();

local.xml

<?xml version="1.0" encoding="UTF-8" ?>
<layout>
    <bazinga>
        <reference name ="content">
            <block type="core/text" name="bazinga" before="-">
                <action method="setText"><text>bazinga!</text></action>
            </block>
        </reference>
    </bazinga>
</layout>

Then go to Catalog->Manage Categories->Category->Custom Design tab, and add 'bazinga' as Layout Handle. Of course you could use another handle name and content. You could also use your module to add observer and category attribute.

Related Topic