首页 文章

使用CMS页面进行布局更新的正确方法是什么?

提问于
浏览
8

我有一个我编写的特色产品模块,它在页面上放置了一个自定义块,其中列出了与块中定义的任何属性相匹配的产品 . 最初我通过在CMS页面的“内容”部分添加 {{block...}} 行来实现它 . 这很好,但我没有得到寻呼机 . 所以,我通过从Content部分删除 {{block...}} 行并将XML添加到Layout Update XML部分来解决这个问题:

<reference name="content">
    <block type="cms/block" name="product_list_top" />
    <block type="vps_featured/list" name="vps_featured_list" template="catalog/product/sale_list.phtml">
        <block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml">
            <block type="page/html_pager" name="product_list_toolbar_pager"/>
        </block>
        <action method="setToolbarBlockName"><name>product_list_toolbar</name></action>
        <action method="setAttributeName"><name>my_attribute</name></action>
    </block>
</reference>

这也很有效 . 然后我决定,因为这个块的实例太多了,如果我将XML文件添加到我的主题的布局文件夹中并将此代码放在那里,那将会更加清晰 . 然后,在布局更新部分,我可以简单地改为:

<reference name="vps_featured_list">
    <action method="setAttributeName"><name>other_attribute</name></action>
</reference>

所以,我创建了一个名为 vps_featured.xml 的文件并将其添加到它:

<layout version="0.1.0">
    <default>
        <reference name="content">
            <block type="cms/block" name="product_list_top" />
            <block type="vps_featured/list" name="vps_featured_list" template="catalog/product/sale_list.phtml">
                <block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml">
                    <block type="page/html_pager" name="product_list_toolbar_pager" />
                </block>
                <action method="setToolbarBlockName"><name>product_list_toolbar</name></action>
            </block>
        </reference>
    </default>
</layout>

我的自定义特色模块在 config.xml 中引用了此布局更新XML文件 . 我天真地认为,当我的VPS特色块在页面上时, vps_featured.xml 才会被合并到页面布局中,这只会发生在特殊CMS页面上的这几个实例中 . 显然事实并非如此 . 这打破了其他每一页,我猜是因为它覆盖了默认句柄 .

所以这引出了我的问题#1: When are the layout xml files included in the page layout? Are they used for ALL pages, regardless of whether or not the module referencing them is actually used?

然后我决定尝试添加一个新的布局句柄,我可以在我的CMS页面中引用它 . 我修改了我的布局XML文件,因此主要部分在 <vps_featured_list> 标签内,而不是 <default> 标签 . 这使其他页面恢复了生机,但当然,我的CMS页面不再有效,因为那些页面上没有使用布局更新句柄 . 我尝试将 <update handle="vps_featured_list" /> 添加到CMS页面的布局更新XML部分,但这并没有预期它 .

所以这让我想到了问题#2: What's the correct way to accomplish this?

这听起来不应该是这么困难,但显然我错过了一些东西 . 我已经阅读了所有我可以在布局上找到的内容,但它们总是很简单的例子,例如“将它添加到每个产品页面” . 我不想在每个cms页面添加一些东西......只是其中一些 . 我是否坚持使用布局更新XML部分来处理相关的CMS页面?我觉得必须有一个更清洁的方式 .

谢谢,

布赖恩

2 回答

  • 3

    节点 <default/> 称为"layout handle" . 每个进入Magent的请求都会生成许多这样的句柄 . 检查Layout tab on the Commerce Bug demo站点以了解生成的各种句柄 .

    Magento将 all 布局XML文件合并到一个称为包布局的巨树中 . 然后,句柄确定哪些Layout XML Update片段用于特定请求 . 这些片段组合到页面布局中 . 正如您所知, <default/> 句柄已添加 always ,这就是为什么您要对系统中的每个站点进行加密 .

    坏消息是虽然有一个CMS页面的句柄,( <cms_page_view /> ),它仍然是一个全有或全无的事情 . 您可以向所有CMS页面添加内容,但不能添加特定的CMS页面 . 所以,是的,CMS管理员的布局更新XML部分是"the right"方式来做你想要的 .

    好消息是到目前为止已经提出了's two approaches you can take that are cleaner than what you' . 首先,您可以通过在XML文件中定义自己的句柄来稍微清理一下,然后使用特殊的Layout XML命令来包含该句柄 .

    在XML中,在自定义句柄中添加Layout Update XML片段 .

    <layout version="0.1.0">  <my_fancy_pants_unique_handle_name_which_doesnt_conflict_with_existing_names>
            <reference name="content">
                <block type="cms/block" name="product_list_top" />
                <block type="vps_featured/list" name="vps_featured_list" template="catalog/product/sale_list.phtml">
                    <block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml">
                        <block type="page/html_pager" name="product_list_toolbar_pager" />
                    </block>
                    <action method="setToolbarBlockName"><name>product_list_toolbar</name></action>
                </block>
            </reference>
        </my_fancy_pants_unique_handle_name_which_doesnt_conflict_with_existing_names>
    </layout>
    

    然后在CMS Admin中,为所需页面添加以下布局更新XML

    <update handle="my_fancy_pants_unique_handle_name_which_doesnt_conflict_with_existing_names" />
    

    Magento允许布局更新XML片段为请求添加其他句柄 . 这就是你上面所做的 . 这样可以清理一些事情,如果你想改变一些XML,那么就有一个集中的地方 .

    Update :事实证明<update />命令可以从布局XML文件本身使用 only . 加载CMS页面的布局更新XML的代码与加载和处理XML文件更新的代码不同 . Magento将 literally 在CMS表单中添加任何内容作为布局更新 . 它不会为递归更新处理它 . 所以,将这样的东西添加到 local.xml 就行了

    <mock_product_list>
        <reference name="head">
        <label>Mock Product List</label>        
                    <action method="addItem"><type>skin_js</type><name>js/sw/wall.js</name></action>
        </reference>    
    </mock_product_list>
    
    <cms_page_view>
        <update handle="mock_product_list" />
    </cms_page_view>
    

    但是,您无法通过CMS管理员应用更新直接执行此操作 . 活到老,学到老 .

    总而言之,小部件方法可能仍然可行,并且可以替代上述方法 .

    • 使用自定义块类创建自定义模块

    • 块类不呈现HTML

    • 块类包含一个名为“addFooToLayout”的方法

    然后,在您的CMS页面中,添加如下更新

    <block type="yourmodule/yourblock" name="unique_name" alias="unique_name">
        <action method="addFooToLayout" />
    </block>
    

    然后在你的块定义中

    public addFooToLayout()
    {
        $layout = Mage::getSingleton('core/layout');
        $head   = $layout->getBlock('head');
        $head->addItem('skin_js','js/sw/wall.js');
        //etc...
    }
    

    有点像 should 工作,并且更清晰一些(取决于你想要添加多少布局更新XML) . 但是,我还没有对这个产品感到震惊,所以买家要小心 .

    第二种方法是create a single widget,它包含您要添加到页面的内容,然后使用窗口小部件实例管理员将该窗口小部件添加到特定页面上的特定块 . 这个链接应该让你开始 .

    最后,冒着成为先令的风险,我最近自我出版了a book on Magento Layouts,深入涵盖了这些问题 . 它's worth your time if you'对了解整个系统的工作方式很感兴趣 .

  • 17

    不过这个问题已经很老了,我通过谷歌找到了它,并希望为将来阅读这篇文章的人添加一些信息 .

    昨天当我读到这个问题和答案,以及thisthis帖子时,我非常确定只有特定页面才能覆盖/扩展CMS页面布局句柄 . 这促使我开发了一个小扩展,它在任何特定页面中注入任何自定义布局句柄 . 我将尽快通过公共链接更新此帖子 .

    但后来我发现实际上可以只为CMS页面创建一个新模板,并为该模板分配任何自定义布局句柄,例如,请参阅Marius的this question and answer . 以下是该代码示例的重要部分:

    <global>
        <page>
            <layouts> 
                <lookbook module="page" translate="label">
                    <label>Lookbook</label>
                    <template>page/1column-lookbook.phtml</template>
                    <layout_handle>lookbook</layout_handle>
                </lookbook> 
            </layouts>
        </page>
    </global>
    

    将任何自定义布局句柄注入任何页面都很容易,并且只对使用此模板和自定义布局句柄的页面执行任何操作 . 我希望我之前知道,希望这篇文章能节省一些人的时间 .

相关问题