在Magento中有条件地设置模板


Conditionally setting the template in Magento

我想让页面的一部分可以通过AJAX获得。我想使用一个URL参数bare,它会告诉Magento使用应用于块的不同模板来呈现页面。模板如下所示:

<?php echo $this->getChildHtml('content'); ?>

就是这样!这个想法是,JavaScript方法可以只获取另一个页面的content,并在适当的时候将其插入DOM。(我不希望这只适用于任何页面——只适用于在布局xml中标记为这样做的页面。)

我在其他地方读到,我应该避免使用条件布局xml。我能想到的唯一其他方法是覆盖Page/Html块本身,创建一个修改后的setTemplate方法,如下所示。本能地,我担心会推翻马根托的核心部分。

public function setTemplate($template, $bareTemplate='')
{
    $bareMode = Mage::app()->getRequest()->getParam('bare');
    $targetTemplate = (!empty($bareTemplate) && $bareMode === '1') ? $bareTemplate : $template;
    return parent::setTemplate($targetTemplate);
}

我还没有想到什么更好的方法?

获得所需内容的关键是删除root作为输出块,并将其替换为content。输出块只是renderLayout()的入口点;

要在Magento中做到这一点,而不包括路径黑客Mage_Core_Controller_Varien_Action,请观察在基本操作控制器类中激发的controller_action_layout_render_before_$this->getFullActionName()范围内的事件(参考Mage_Core_Controller_Varien_Action::renderLayout()方法)。

首先配置您的模型类组和前端事件观察器。您需要确定任何需要此逻辑的路由的完整操作名称。参见Mage_Core_Controller_Varien_Action::renderLayout()。下面的配置示例。

<?xml version="1.0"?>
<config>
    <global>
        <models>
            <your_classgroup>
                <class>Your_Classgroup_Model</class>
            </your_classgroup>
        </models>
    </global>
    <frontend>
        <events>
            <controller_action_layout_render_before_FULL_ACTION_NAME...>
                <observers>
                    <your_observer_config>
                        <type>model</type>
                        <class>your_classgroup/observer</class>
                        <method>makeContentBlockTheOutputBlock</method>
                    </your_observer_config>
                </observers>
            </controller_action_layout_render_before_FULL_ACTION_NAME...>
        </events>
    </frontend>
</config>

事件观测器逻辑很简单。这样做:

public function makeContentBlockTheOutputBlock($observer)
{
   //Edit: action not passed in to this event; passed in generic generate_blocks event
   if( Mage::app()->getRequest()->getParam('bare') )
   {
        Mage::app()->getLayout()->removeOutputBlock('root')->addOutputBlock('content');
   }
}

HTH。