结帐时出错 - AddBodyClass

时间:2013-04-19 13:19:50

标签: xml magento layout checkout

我在local.xml中添加了以下内容,以便在客户登录时添加额外的body类:

<customer_logged_in>
<reference name="root">
  <action method="addBodyClass">
    <classname>logged-in</classname>
  </action>
</reference>
</customer_logged_in>

这样可行,但当我转到onepage checkout时,我收到以下错误:

a:5:{i:0;s:98:"Invalid method Mage_Checkout_Block_Onepage_Progress::addBodyClass(Array
(
[0] => logged-in
)
)";i:1;s:1967:"#0 [internal function]: Varien_Object->__call('addBodyClass', Array)
#1 [internal function]: Mage_Checkout_Block_Onepage_Progress->addBodyClass('logged-in')

2 个答案:

答案 0 :(得分:5)

您的布局更新假定所有“根”块都继承自Mage_Page_Block_Html,即使用addBodyClass()方法的类。不幸的是,这种情况并非如此。我认为没有一个简单的解决方法。

您可以通过创建观察者并挂钩core_block_abstract_to_html_before事件来完成您尝试执行的操作。从那里,您可以检查客户是否已登录,检索正在呈现的块,并在检查其是否具有该方法后(或在try块内)调用addBodyClass()。但这可能相当昂贵,因为每页加载会多次调用 - 每个块一次。

作为hack,您可以覆盖Mage_Core_Block_Abstract类并将addBodyClass()方法复制到它。这应该可行,但它被认为是不好的做法,因为它与试图覆盖Mage_Core_Block_Abstract的任何其他模块冲突。

答案 1 :(得分:5)

cameronhimself非常关注根块是Mage_Page_Block_Html继承的假设。我做了同样的假设,我的代码完全相同!我还发现这打破了一些与checkout相关的逻辑(严格来说,它违反了AJAX逻辑,并没有使用Mage_Page_Block_Html作为根块)。

然而,作为对cameronhimselfs回答的改进,实际上很容易通过观察者添加身体类而不需要观察core_block_abstract_to_html_before。只有捕获你需要一个模块。因此,您需要为此目的制作一个或使用现有的有意义的。然后,最好是,我们想要挂钩每个页面加载总是一次触发的事件。

嗯,有这样的事件。 benmarks提供了一个非常好的简洁answer to another question,它给了我们一些提示。从那以后,你可以看到好的事件可能是controller_action_layout_generate_blocks_after

所以通过照常观察事件:

<controller_action_layout_generate_blocks_after>
    <observers>
        <tghpcore_controller_action_layout_generate_blocks_after>
            <type>singleton</type>
            <class>yourmodule/observer</class>
            <method>addBodyClasses</method>
        </tghpcore_controller_action_layout_generate_blocks_after>
    </observers>
</controller_action_layout_generate_blocks_after>

您可以在观察者类中干净利落地安全地达到同样目的:

public function addBodyClasses($observer)
{
    /** @var $layout Mage_Core_Model_Layout */
    $layout = $observer->getEvent()->getLayout();
    // Retrieve the root block
    $root = $layout->getBlock('root');
    // Be 100% sure that there is a root block
    if($root) {
        // Check that the root block is a Magento page block that we can add body classes to
        if(is_a($root, 'Mage_Page_Block_Html')) {
            // Add logged in/out body classes
            if(Mage::helper('customer')->isLoggedIn()) {
                $root->addBodyClass('logged-in');
            } else {
                $root->addBodyClass('logged-out');
            }
            // You can even add more conditions and body classes for whatever you may want here
        }
    }
}

非常适合我。希望它也适合你!