Как проверить, существует ли блок (в зависимости от его типа)
-
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
.т.е.
$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>
.
Observer:
public function generateBlocks($observer)
{
/**
* @var $block Mage_Core_Block_Abstract
*/
$block = $observer->getEvent()->getBlock();
if ($block->getType() == 'cms/block') {
//do something
}
}
.
См. Генеракодицетагкод генеракодицетагкода, если вы хотите сделать некоторые изменения.
Обновление (другое решение)
<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>
.
<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>
Observer.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);
}
Насколько я помню, вы можете получить все блоки в качестве коллекции или как массив из макета, а затем цикл, проверяя их тип с использованием оператора «экземпляра».