我打算对 JBreton 的精彩回答发表评论,但是将我带到这个线程的特定用例略有不同。(而且我是一个潜伏者,还没有足够的声誉发表评论。)
即使在尝试观察各种事件之后,接受的答案和修改 PHP 代码布局的其他建议对我也不起作用,所以我想我会在 JBreton 方面发布一个窃取/支持/示例答案。我的用例是根据某些条件以编程方式从 checkout_cart_index 布局中删除块(核心和自定义模块块)。使用自定义布局句柄的方法也适用于 ADDING 块,因为它只是“激活”Magento 将从主题中的标准布局 XML 文件处理的新句柄。
JBreton 的方法是我尝试过的所有方法中最好的。就当前和未来的需求而言,它更有意义。尤其是在设计师和模板构建者不是应该在 PHP 代码中四处寻找的人的情况下。模板人知道 XML 并且无论如何都应该非常熟悉 Magento 的布局 XML 系统。因此,使用自定义句柄来修改特定编程条件下的布局是比在 PHP 中通过字符串添加 XML 更好的方法。
再次......这不是我自己想出的解决方案......我从上面 JBreton 的回答中偷了这个,并提供了我的分身可以在他们的情况下使用的示例代码作为额外的起点。请注意,此处并未包含我的所有模块代码(尤其是 app/modules XML 文件、模型类等)。
我的模块的配置文件:
app/code/local/Blahblah/GroupCode/etc/config.xml
<config>
... other config XML too ...
<frontend>
<events>
<controller_action_layout_load_before>
<observers>
<blahblah_groupcode_checkout_cart_index>
<type>singleton</type>
<class>Blahblah_Groupcode_Model_Ghost</class>
<method>checkout_cart_prepare</method>
</blahblah_groupcode_checkout_cart_index>
</observers>
</controller_action_layout_load_before>
</events>
</frontend>
</config>
类中观察者的方法:
app/code/local/Blahblah/GroupCode/Model/Observer.php
<?php
public function checkout_cart_prepare(Varien_Event_Observer $observer)
{
// this is the only action this function cares to work on
$fullActionName = 'checkout_cart_index';
... some boring prerequiste code ...
// find out if checkout is permitted
$checkoutPermitted = $this->_ghost_checkoutPermitted();
if(!$checkoutPermitted)
{
// add a custom handle used in our layout update xml file
Mage::app()->getLayout()->getUpdate()->addHandle($fullActionName . '_disable_checkout');
}
return $this;
}
主题文件中包含的布局更新:
app/design/PACKAGE/THEME/etc/theme.xml
<?xml version="1.0"?>
<theme>
<parent>...</parent>
<layout>
<updates>
<!-- Adding references to updates in separate layout XML files. -->
<blahblah_checkout_cart_index>
<file>blahblah--checkout_cart_index.xml</file>
</blahblah_checkout_cart_index>
... other update references too ...
</updates>
</layout>
</theme>
布局更新定义文件:
app/design/PACKAGE/THEME/layout/blahblah--checkout_cart_index.xml
<layouts>
<checkout_cart_index_disable_checkout>
<reference name="content">
<block type="core/template" name="checkout.disabled" as="checkout.disabled" before="-" template="checkout/disabled-message.phtml" />
<remove name="checkout.cart.top_methods" />
<remove name="checkout.cart.methods" />
</reference>
</checkout_cart_index_disable_checkout>
... other layout updates too ...
</layouts>
(是的,我的模块中还有其他代码可以监视结帐过程事件,以确保不会有人通过手动 URL 路径潜入。并且其他检查已到位以真正“禁用”结帐。我只是展示我如何通过观察者以编程方式修改布局的示例。)