Answers:
为什么更改根模板不起作用
都
Mage_Cms_IndexController::indexAction()
和
Mage_Cms_IndexController::viewAction()
负责显示默认主页和CMS页面的页面分别调用帮助程序:
Mage::helper('cms/page')->renderPage($this, $pageId)
如果您跳入帮助程序(位于app / code / core / Mage / Cms / Helper / Page.php)并遵循renderPage()
受保护的方法,_renderPage()
您将看到Magento两次检查根模板(Magento CE 1.7。 0.2):
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());
}
这两个调用都在处理了诸如“ cms_page”之类的布局句柄之后发生,因此您在这里很不走运。
您可以做什么来更改根模板
cms_page_render
您可以使用一个事件在CMS页面上添加自己的XML布局句柄。创建您自己的扩展程序(我将在此处保留一些详细信息)并在您的中配置事件观察器config.xml
:
<?xml version="1.0"?>
<config>
<modules>
<Emzee_Cms>
<version>0.0.1</version>
</Emzee_Cms>
</modules>
<global>
<events>
<cms_page_render>
<observers>
<emzee_cms_page_render>
<class>emzee_cms/observer</class>
<method>cms_page_render</method>
</emzee_cms_page_render>
</observers>
</cms_page_render>
</events>
<models>
<emzee_cms>
<class>Emzee_Cms_Model</class>
</emzee_cms>
</models>
</global>
</config>
添加事件观察者:
<?php
class Emzee_Cms_Model_Observer
{
public function cms_page_render(Varien_Event_Observer $observer)
{
$action = $observer->getEvent()->getControllerAction();
$actionName = strtolower($action->getFullActionName());
$action->getLayout()->getUpdate()
->addHandle($actionName . '_after');
return $this;
}
}
最后,添加新的布局XML句柄(例如在中local.xml
):
<?xml version="1.0"?>
<layout version="0.1.0">
<cms_index_index_after>
<reference name="root">
<action method="setTemplate"><template>page/1column.phtml</template></action>
</reference>
</cms_index_index_after>
</layout>
您也可以使用此方法来添加一个cms_page_view_after
句柄,或在cms_page_render
将$page
对象传递给观察者时创建页面特定的句柄。
为什么您不能在“参考左侧”添加块
您确定所使用的模板有左列吗?这个问题听起来很愚蠢,但是例如默认的“带有右栏的2列”布局仅提供了“内容”和“正确”区域。我可以将块添加到正确的列使用cms_page
而不会出现问题,所以这可能是问题所在。
通常,您只能轻松地将块添加到引用中,并在以下情况下回显它们:
app/design/frontend/base/default/template/page/*.phtml
),然后core/text_list
,$this->getChildhtml()
不带参数的调用,或者执行其他操作以回显所有子块。没有更多详细信息,我无法告诉您为什么在左侧或右侧列中未回显您的块。
$cmsPageId = '_' . str_replace('-', '_', $observer->getEvent()->getPage()->getIdentifier());
如果有人更改了cms页面的URL,则该句柄将不会起作用。理想情况下,管理系统中的CMS页面上将存在“页面密钥”字段,然后可以更改页面url,名称等,并且密钥可以保持不变。
关于“无法使用<reference name="left
/> 添加块,是否确定CMS页面上有一个名为left的块?例如,如果您考虑Magento示例数据附带的默认主页,它似乎有一个名为剩下。
但是,如果您查看后端中的页面,则可以看到它已设置为使用根模板
`2 columns with right bar`
然后在其内容区域中,使用HTML标记添加左列(将所见即所得切换为源视图)
<div class="col-left side-col">
<p class="home-callout"><a href="{{store direct_url="apparel/shoes/womens/anashria-womens-premier-leather-sandal.html"}}"><img src="{{skin url='images/ph_callout_left_top.gif'}}" alt="" border="0" /></a></p>
<p class="home-callout"><img src="{{skin url='images/ph_callout_left_rebel.jpg'}}" alt="" border="0" /></p>
{{block type="tag/popular" template="tag/popular.phtml"}}</div>
这个有向图使您清楚地知道没有块left
可以挂接到(单击以查看大图)
关于设置模板,如果您查看“布局”下拉列表的来源
<select id="page_root_template" name="root_template" class=" required-entry select">
<option value="empty">Empty</option>
<option value="one_column">1 column</option>
<option value="two_columns_left">2 columns with left bar</option>
<option value="two_columns_right" selected="selected">2 columns with right bar</option>
<option value="three_columns">3 columns</option>
</select>
当你设置此字段中可以看到,得到保存的实际值是一样的东西one_column
,two_columns_left
等等,这些值corespond同名的布局句柄。
#File: app/design/frontend/default/modern/layout/page.xml
<page_one_column translate="label">
<label>All One-Column Layout Pages</label>
<reference name="root">
<action method="setTemplate"><template>page/1column.phtml</template></action>
<!-- Mark root page block that template is applied -->
<action method="setIsHandle"><applied>1</applied></action>
<action method="setLayoutCode"><name>one_column</name></action>
</reference>
</page_one_column>
...
<page_two_columns_left translate="label">
<label>All Two-Column Layout Pages (Left Column)</label>
<reference name="root">
<action method="setTemplate"><template>page/2columns-left.phtml</template></action>
<!-- Mark root page block that template is applied -->
<action method="setIsHandle"><applied>1</applied></action>
<action method="setLayoutCode"><name>two_columns_left</name></action>
</reference>
</page_two_columns_left>
Magento渲染CMS页面时,它引用保存的值,并向页面添加适当的布局句柄。与问题相切时,在此处添加了该句柄
#File: app/code/core/Mage/Cms/Helper/Page.php
protected function _renderPage(Mage_Core_Controller_Varien_Action $action, $pageId = null, $renderLayout = true)
{
//...
$action->addActionLayoutHandles();
if ($page->getRootTemplate()) {
$handle = ($page->getCustomRootTemplate()
&& $page->getCustomRootTemplate() != 'empty'
&& $inRange) ? $page->getCustomRootTemplate() : $page->getRootTemplate();
$action->getLayout()->helper('page/layout')->applyHandle($handle);
}
//...
}
更重要的是布局句柄的添加顺序
如您在上面的屏幕截图中所见,该page_two_columns_right
句柄被添加到该cms_index_index
句柄之后。这意味着,如果您添加布局xml更新代码以更改代码中的模板,则该模板cms_index_index
将运行,但是其中的布局更新xml代码page_two_columns_right
将在其后运行。
我一直怀疑这是设计使然,以确保在用户界面中设置的模板始终正确。在以前版本的Magento中<action method="setIsHandle"><applied>1</applied></action>
,由于相同的原因,似乎存在方法调用。
因此,没有办法使用纯布局xml代码执行您想要的操作。如果您对创建自定义模块和观察者代码感到满意,请调查该cms_page_render
事件。这会在loadLayoutUpdates
调用之前立即触发,并使您可以在其中滑入其他句柄名称,或删除现有的句柄名称。
default
手柄中设置模板,则在管理员中设置的布局仍将获胜(即page_two_columns_right
仍将运行)后来)。另外,关于Re:术语-您不会覆盖句柄,您的句柄始终与其他句柄共存-只是它们运行的顺序会影响最终结果。