Как проверить, существует ли блок (в зависимости от его типа)

magento.stackexchange https://magento.stackexchange.com//questions/32324

Вопрос

Это меня очень смущает!!

Я пришел к ситуации, когда мне нужно создать новый блок (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>
.

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);
}

Насколько я помню, вы можете получить все блоки в качестве коллекции или как массив из макета, а затем цикл, проверяя их тип с использованием оператора «экземпляра».

Лицензировано под: CC-BY-SA с атрибуция
Не связан с magento.stackexchange
scroll top