【问题标题】:Custom layouts for catalog_category_view on MagentoMagento 上 catalog_category_view 的自定义布局
【发布时间】:2015-01-30 18:57:34
【问题描述】:

我需要能够为不同的类别使用不同的布局,在类别的自定义设计选项卡和页面布局字段中选择。

我正在使用 Magento 1.9.1.0。

在我的 config.xml 我有:

<global>
    <page>
        <layouts>
            <module_home module="page" translate="label">
                <label>Module Home</label>
                <template>page/base.phtml</template>
                <layout_handle>module_home</layout_handle>
            </module_home>

            <module_categories module="page" translate="label">
                <label>Module Categories</label>
                <template>page/base.phtml</template>
                <layout_handle>module_categories</layout_handle>
            </module_categories>
        </layouts>
    </page>
    ...

在我的layouts.xml 文件中,我有:

<default>
    <reference name="root">...</reference>
</default>
<module_home translate="label">...</module_home>
<module_categories translate="label">...</module_categories>

当我从类别的管理员中选择 Module Categories 布局时,我没有得到 module_categories 处理程序的更改,只有在 &lt;default&gt; 上设置的更改。

如果我这样强迫它:

<catalog_category_view>
    <update handle="module_categories" />
</catalog_category_view>

我确实得到了更改,但我想要多个处理程序,在管理员上选择为布局。

也许我做错了什么?找不到如何执行此操作的示例,也许您可​​以指出某个地方?谢谢!

【问题讨论】:

    标签: php magento magento-1.9


    【解决方案1】:

    &lt;update /&gt; 指令让您有了正确的想法。只需将其放在管理员中您类别的Custom Layout Update 字段中,该类别应应用该布局句柄。您仍然可以使用Page Layout 字段设置页面模板。

    您需要使用 &lt;update /&gt; 指令显式指定布局句柄的原因是因为 Magento 的类别控制器不使用 layout_handle 节点,而 Magento 的其他部分,如 Magento 的 CMS 页面控制器,使用它。

    比如我们看Mage_Cms_PageController,它负责渲染一个CMS页面:

    public function viewAction()
    {
        $pageId = $this->getRequest()
            ->getParam('page_id', $this->getRequest()->getParam('id', false));
        if (!Mage::helper('cms/page')->renderPage($this, $pageId)) {
            $this->_forward('noRoute');
        }
    }
    

    让我们深入挖掘,看看Mage_Cms_Helper_Page::renderPage(),它调用了Mage_Cms_Helper_Page::_renderPage()

    protected function _renderPage(Mage_Core_Controller_Varien_Action  $action, $pageId = null, $renderLayout = true)
    {
    
        $page = Mage::getSingleton('cms/page');
    
        /* ... */
    
        if ($page->getRootTemplate()) {
            $handle = ($page->getCustomRootTemplate()
                        && $page->getCustomRootTemplate() != 'empty'
                        && $inRange) ? $page->getCustomRootTemplate() : $page->getRootTemplate();
            $action->getLayout()->helper('page/layout')->applyHandle($handle);
        }
    
        /* ... */
    
        if ($page->getRootTemplate()) {
            $action->getLayout()->helper('page/layout')
                ->applyTemplate($page->getRootTemplate());
        }
    
        /* ... */
    }
    

    我们在这里看到两个重要的逻辑。

    首先,_renderPage() 调用 $action-&gt;getLayout()-&gt;helper('page/layout')-&gt;applyHandle($handle)。如果您深入挖掘,您会发现 Mage_Page_Helper_Layout::applyHandle() 负责应用配置 XML 定义的适当 layout_handle

    public function applyHandle($pageLayout)
    {
        $pageLayout = $this->_getConfig()->getPageLayout($pageLayout);
    
        if (!$pageLayout) {
            return $this;
        }
    
        $this->getLayout()
            ->getUpdate()
            ->addHandle($pageLayout->getLayoutHandle());
    
        return $this;
    }
    

    其次,_renderPage() 调用 $action-&gt;getLayout()-&gt;helper('page/layout')-&gt;applyTemplate($page-&gt;getRootTemplate())。与applyHandle() 类似,applyTemplate() 应用实际的页面模板。

    因此,这就解释了为什么在涉及 CMS 页面时,您可以依赖配置 XML 中定义的 layout_handle。现在,让我们找出为什么它对类别不可靠。

    我们看Mage_Catalog_CategoryController::viewAction(),它负责显示一个分类页面:

    public function viewAction()
    {
        if ($category = $this->_initCatagory()) {
            $design = Mage::getSingleton('catalog/design');
            $settings = $design->getDesignSettings($category);
    
            /* ... */
    
            // apply custom layout update once layout is loaded
            if ($layoutUpdates = $settings->getLayoutUpdates()) {
                if (is_array($layoutUpdates)) {
                    foreach($layoutUpdates as $layoutUpdate) {
                        $update->addUpdate($layoutUpdate);
                    }
                }
            }
    
            /* ... */
    
            // apply custom layout (page) template once the blocks are generated
            if ($settings->getPageLayout()) {
                $this->getLayout()->helper('page/layout')->applyTemplate($settings->getPageLayout());
            }
    
            /* ... */
        }
        elseif (!$this->getResponse()->isRedirect()) {
            $this->_forward('noRoute');
        }
    }
    

    剥离所有默认布局逻辑,我们只剩下两部分:

            // apply custom layout update once layout is loaded
            if ($layoutUpdates = $settings->getLayoutUpdates()) {
                if (is_array($layoutUpdates)) {
                    foreach($layoutUpdates as $layoutUpdate) {
                        $update->addUpdate($layoutUpdate);
                    }
                }
            }
    

    这将通过类别的布局更新(如管理员中的 Custom Layout Update 字段中所定义)并应用它们。这就是使用 &lt;update handle="some_handle" /&gt; 有效的原因。

    还有……

            // apply custom layout (page) template once the blocks are generated
            if ($settings->getPageLayout()) {
                $this->getLayout()->helper('page/layout')->applyTemplate($settings->getPageLayout());
            }
    

    这将应用自定义页面模板,类似于 CMS 页面逻辑的做法,使用 Mage_Page_Helper_Layout::applyTemplate()

    现在,发现有什么遗漏了吗?

    是的,类别控制器不会调用 Mage_Page_Helper_Layout::applyHandle() 来应用配置 XML 中定义的 layout_handle。这意味着您可以使用 Page Layout 字段为类别指定特定的页面模板,但不会应用模板随附的 layout_update

    希望这可以弄清楚为什么您的 layout_update 节点没有像您期望的那样在类别页面上得到使用。 Magento 充满了像这样的奇怪行为和不一致:)

    【讨论】:

    • 感谢您的帮助。如果我已经选择与页面布局中的布局相同的句柄,我不清楚为什么需要在自定义布局更新上设置更新句柄?也许我对 Magento 的工作原理一无所知?
    • 我编辑了我的答案并添加了重要的额外细节,说明为什么您的layout_handle 没有像您想象的那样被应用。希望这有助于澄清事情! :)
    • 真的很感谢花时间写这篇文章,因为我现在明白了一些事情。确实不是我期望 Magento 做的事情。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2013-09-28
    • 1970-01-01
    • 2015-01-16
    • 2013-09-13
    • 2022-12-15
    • 2015-02-23
    • 2010-11-09
    • 2011-05-22
    相关资源
    最近更新 更多