这真的让我很困惑!

我遇到了一种情况,我需要创建一个新块(core/template 如果页面布局中存在 CMS 块,则以编程方式。一般来说,据我所知,有两种解决方法。

1.通过布局添加块

在大多数情况下,这是完成此任务的最佳主意。如果有合适的布局句柄可用,我们可以向页面添加一个块。但不幸的是,就我而言,我没有任何可用的静态块特定布局句柄(对于 cms 页面,我们知道有 cms_page 处理)。所以我不能依赖这个方法

2.使用观察者

第二种方法是听取适当观察者的意见。同样,我找不到在布局/块加载期间触发的基于静态块的观察者。然而,有一些我可以信赖的一般观察家。我认为 controller_action_layout_generate_blocks_before 可以用在我的情况下。但在这里我面临着真正的问题

我真正的问题

所以当我使用 controller_action_layout_generate_blocks_before 就我而言,问题是,我无法根据块的类型检索块。我可以根据它们过滤块 name, ,但不是基于他们的 type. 。IE

$observer->getEvent()->getLayout()->getBlock('block_name'); //this work; Used name
$observer->getEvent()->getLayout()->getBlock('cms/block'); //this wont; use type

事实上我不能依赖名字。 因为我想得到全部 cms/block 输入块并在检查我使用静态块设置的一些自定义属性后添加新模板

那么我怎样才能得到所有 cms/block 通过观察者?有可能吗?请分享您的想法。

有帮助吗?

解决方案

用这个:

           <core_block_abstract_prepare_layout_before>
                <observers>
                    <ssd_test>
                        <class>ssd_test/observer</class>
                        <method>generateBlocks</method>
                        <type>singleton</type>
                    </ssd_test>
                </observers>
            </core_block_abstract_prepare_layout_before>

观察员:

public function generateBlocks($observer)
    {
        /**
         * @var $block Mage_Core_Block_Abstract
         */
        $block = $observer->getEvent()->getBlock();
        if ($block->getType() == 'cms/block') {
            //do something
        }
    }

参考 protected function _toHtml()Mage_Cms_Block_Block 如果你想做一些改变。

更新(另一个解决方案)

    <controller_action_layout_generate_blocks_after>
        <observers>
            <ssd_test>
                <class>ssd_test/observer</class>
                <method>generateBlocks</method>
                <type>singleton</type>
            </ssd_test>
        </observers>
    </controller_action_layout_generate_blocks_after>

观察者.php:

public function generateBlocks($observer)
    {
        /**
         * @var $l Mage_Core_Model_Layout
         */
        $l = $observer->getEvent()->getLayout();

        $newBlock = $l->createBlock(
            'Mage_Core_Block_Template',
            'new_block_name_here',
            array('template' => 'some_template.phtml')
        );

        foreach ($l->getAllBlocks() as $block) {
            if ($block->getType() == 'cms/block') {
                $l->getBlock('some_block_name')->append($newBlock);
            }
        }
    }

其他提示

你能不能简单地听听事件 core_block_abstract_to_html_before 然后检查事件的块类型并据此更新模板?像下面这样的事情应该可以做到。

$block = $observer->getBlock();
if ($block instanceof Mage_Cms_Block_Block) {
    // Make your changes here
}

这适用于所有块,但如果您知道这只发生在少数情况下,那么我建议通过布局 xml 更改模板。

或者,如果您想将某些内容附加到块但保留原始内容,您可以使用 core_block_abstract_to_html_after 得到 transport 传递给事件。然后根据此设置 html 并附加您需要的内容。这个事件再次为您提供了阻止,因此您可以如此简单地限制您的代码 Mage_Cms_Block_Block

$block = $observer->getBlock();
if ($block instanceof Mage_Cms_Block_Block) {
    $transport = $observer->getTransport();
    $html = $transport->getHtml();
    $html .= 'We need to append something here';
    $transport->setHtml($html);
}

据我记得,您可以从布局中获取所有块作为集合或数组,然后使用“实例”运算符循环检查它们的类型。

许可以下: CC-BY-SA归因
scroll top