我试图改变一个块的模板(view.phtml)( product.info)用于商品详细页,要做到这一点,我观察的事件(controller_action_layout_generate_blocks_before),它做必要的检查,我试图改变块的模板后, (product.info)以下方式:
$layout = $observer->getEvent()->getLayout();
$layout->getUpdate()->addUpdate('
<reference name="product.info">
<action method="setTemplate">
<template>customlayout/product/view.phtml</template>
</action>
</reference>');
$layout->getUpdate()->load();
$layout->generateXml();
Run Code Online (Sandbox Code Playgroud)
如果我放"<remove name='product.info'/>",它将被删除,但当试图做上述,它不工作.
编辑:
要求是将模板(产品详细信息)动态切换到当前产品中的选定模板(在CustomModule中).
iva*_*dja 24
正如本说的那样,我不知道你为什么要把它放在观察者身上,但你的情况就是问题的序列loadLayout.
您可以使用以下命令检查加载的布局xml:
Mage::log(Mage::getSingleton('core/layout')->getUpdate()->asString());
很确定你的<action method="setTemplate"><template>customelayout/product/view.phtml</template>被其他人覆盖了setTemplate,这就是你的模板没有显示的原因.
Mage_Core_Controller_Varien_Action
public function loadLayout($handles=null, $generateBlocks=true, $generateXml=true)
{
// if handles were specified in arguments load them first
if (false!==$handles && ''!==$handles) {
$this->getLayout()->getUpdate()->addHandle($handles ? $handles : 'default');
}
// add default layout handles for this action
$this->addActionLayoutHandles();
$this->loadLayoutUpdates(); //in here: $this->getLayout()->getUpdate()->load();
if (!$generateXml) {
return $this;
}
//event: controller_action_layout_generate_xml_before
$this->generateLayoutXml(); //in here: $this->getLayout()->generateXml();
if (!$generateBlocks) {
return $this;
}
//event: controller_action_layout_generate_blocks_before, your observer is located here
$this->generateLayoutBlocks(); //in here: $this->getLayout()->generateBlocks();
$this->_isLayoutLoaded = true;
return $this;
}
Run Code Online (Sandbox Code Playgroud)
所以,你将使用事件来修改xml : controller_action_layout_generate_blocks_before.
这意味着你需要做的是:
//add the update
$layout->getUpdate()->addUpdate('<reference name="product.info"><action method="setTemplate"><template>customelayout/product/view.phtml</template></action></reference>');
//then generate the xml
$layout->generateXml();
Run Code Online (Sandbox Code Playgroud)
你的问题是什么原因:
$layout->getUpdate()->load();
之后再次被召唤
$layout->getUpdate()->addUpdate('<reference name="product.info"><action method="setTemplate"><template>customelayout/product/view.phtml</template></action></reference>');
Run Code Online (Sandbox Code Playgroud)
虽然最好使用事件:controller_action_layout_generate_xml_before.这样您就不需要两次生成xml.
Ala*_*orm 16
如果要从观察者更改块的模板,则应该
听取这个controller_action_layout_generate_blocks_after事件
使用PHP来操作布局
通过侦听事件后生成,您将确保首先调用通过基于文件的布局更新XML字符串指定的每个操作方法,并且您的模板更改将"获胜".
我建议使用PHP代码,因为布局更新XML系统是一种特定于域的语言,其目的是为布局更新提供一组有限的功能,而无需编写单行PHP.如果您已经在使用PHP观察器,那么通过PHP操作布局是有意义的.
像这样的代码应该能得到你想要的东西(再次,来自after observer方法)
$controller = $observer->getAction();
//limit to the product view page
if($controller->getFullActionName() != 'catalog_product_view')
{
return;
}
$layout = $controller->getLayout();
$product_info = $layout->getBlock('product.info');
if(!$product_info)
{
Mage::log('Could not find product.info block');
return;
}
$product_info->setTemplate('customelayout/product/view.phtml');
Run Code Online (Sandbox Code Playgroud)
ben*_*rks 13
为什么你这样做呢?
最好使用local.xml布局文件或为自定义模块声明的布局文件来执行此操作:
<?xml version="1.0" encoding="UTF-8"?>
<layout>
<catalog_product_view>
<reference name="product.info">
<action method="setTemplate">
<tpl>customelayout/product/view.phtml</tpl>
</action>
</reference>
</catalog_product_view>
</layout>
Run Code Online (Sandbox Code Playgroud)
<remove/>编辑块名时的FYI ,不会为包含该删除指令的任何渲染范围实例化具有该名称的块.
| 归档时间: |
|
| 查看次数: |
25736 次 |
| 最近记录: |