如何检查块是否存在(根据其类型)
-
11-12-2019 - |
题
这真的让我很困惑!
我遇到了一种情况,我需要创建一个新块(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);
}
据我记得,您可以从布局中获取所有块作为集合或数组,然后使用“实例”运算符循环检查它们的类型。