如何使用布局句柄修改页面布局

时间:2014-09-05 13:51:50

标签: xml magento layout page-layout

我正在创建自定义页面布局。我已将必要的XML添加到我的模块的config.xml文件中,创建了模板,并且可以在管理面板中选择模板。

我似乎无法使用布局句柄修改页面布局。通过修改,我的意思是将JS添加到头部,添加一个body类等。在我的config.xml中,我有以下内容:

<config>
    <frontend>
        ....
        <layout>
            <updates>
                <mymodule_layout>
                   <file>mymodule.xml</file>
                </mymodule_layout>
            </updates>
        </layout>
    </frontend>
    ...
    <global>
        <page>
            <layouts>
                <mymodlue_pagelayout module="page" translate="label">
                    <label>My Module - A Custom Layout</label>
                    <template>page/customlayouttest.phtml</template>
                    <layout_handle>mymodlue_pagelayout</layout_handle>
                </mymodlue_pagelayout>
            </layouts>
        </page>
    ....
    </global>
</config>

然后在mymodule.xml中,我有以下XML。它都不起作用。当我访问应用了我的页面布局的类别时,以下所有更改都不会生效。我错过了什么?

<mymodlue_pagelayout translate="label">
    <label>My Module - A Custom Layout</label>
    <reference name="root">
        <action method="setTemplate"><template>page/customlayouttest.phtml</template></action>
        <!-- Mark root page block that template is applied -->
        <action method="setIsHandle"><applied>1</applied></action>
        <action method="addBodyClass"><className>grid-4</className></action>
        <action method="addBodyClass"><className>stl-category</className></action> 
    </reference>

    <reference name="product_list">
        <action method="setTemplate"><template>catalog/product/list-alternate.phtml</template></action>
        <action method="setData"><name>list_golfers</name><value>true</value></action>
    </reference>

    <reference name="product_list_toolbar">
        <action method="setDefaultGridPerPage"><limit>15</limit></action>
        <action method="addPagerLimit"><mode>grid</mode><limit>15</limit></action>
        <action method="addPagerLimit"><mode>grid</mode><limit>all</limit></action>
    </reference>

    <reference name="head">
        <action method="addJs"><script>jquery/jquery-1.7.1-min.js</script></action>
        <action method="addJs"><script>varien/product.js</script></action>
        <action method="addJs"><script>varien/configurable.js</script></action>
        <action method="addJs"><script>amasty/amconf/configurable.js</script></action>
        <action method="addJs"><script>jquery/magiczoom.js</script></action>
        <action method="addJs"><script>prototype/window.js</script></action>
        <action method="addJs"><script>jquery/jquery-magnificPopup.0.9.9.js</script></action>
    </reference>
</mymodlue_pagelayout>

1 个答案:

答案 0 :(得分:1)

这个问题的简短回答是,Magento根本不使用类别页面上布局句柄中的信息,它实际上是被忽略的。 Alan Storm在类似的SO问题中向我们提供了解释:https://stackoverflow.com/a/20257191/2124039

虽然我们现在知道为什么布局句柄不起作用,但我们仍然需要一个解决方案 - 我们如何使用布局句柄修改页面布局?我发现最简单的解决方案是创建一个侦听事件controller_action_layout_load_before的观察者,确定正在查看的页面是否是一个类别页面,然后将布局句柄添加到我们正在使用的布局页面的布局对象中(如果有的话。

作为独立模块构建,它将是这样的:

config.xml中

<config>
    <modules>
        <Callmetwan_CategoryLayoutHandler>
            <version>1.0.0.0</version>
        </Callmetwan_CategoryLayoutHandler>
    </modules>
    <frontend>
        <events>
            <controller_action_layout_load_before>
                <observers>
                    <pm_shopthelook_model_observer>
                        <class>Callmetwan_CategoryLayoutHandler_Model_Observer</class>
                        <method>addCustomHandles</method>
                    </pm_shopthelook_model_observer>
                </observers>
            </controller_action_layout_load_before>
        </events>
    </frontend>
</config>

observer.php:

class Callmetwan_CategoryLayoutHandler_Model_Observer extends Varien_Object
{
    public function addCustomHandles($observer) {

        $pageConfig         = (object) Mage::getModel('page/config');
        $allLayoutHandles   = (array) $pageConfig->getPageLayoutHandles();


        // Determine if we are in a category
        $category = Mage::registry('current_category');
        $product = Mage::registry('current_product');

        if ($category && !$product)
        {

            // Get all design settings applied to current category
            $design = (object) Mage::getSingleton('catalog/design')->getDesignSettings($category);

            // Get current page layout current category is using
            $pageLayout = (string) $design->getPageLayout();


            foreach ($allLayoutHandles as $layout => $handle)
            {
                // Cycle through each layout to find current layout, then add current page's layout handle to the layout object
                if ($pageLayout === $layout)
                {
                    $update = (object) Mage::getSingleton('core/layout')->getUpdate();
                    $update->addHandle($handle);
                    break;
                }
            }
        }
    }
}

总结一下,你最终会得到两个独立的模块。您的布局页面将是一个模块的一部分(使用问题中的示例,它将是Mymodule),它将定义一个自定义的mymyodule.xml布局文件,其中包含布局页面的所有更新。然后上面的代码(Callmetwan_CategoryLayoutHandler)将负责将布局处理程序添加到布局对象。