Pergunta

Isso realmente me confunde!!

Cheguei a uma situação em que preciso criar um novo bloco (core/template bloco) programaticamente, se houver Bloco CMS presente em um layout de página.Em geral, de acordo com meu conhecimento, existem duas soluções alternativas para isso.

1.Adicione um bloco através do layout

Na maioria dos casos, esta seria a melhor ideia para realizar esta tarefa.Podemos adicionar um bloco a uma página se um identificador de layout apropriado estiver disponível.Mas, infelizmente, no meu caso, não tenho nenhum identificador de layout específico de bloco estático disponível (para páginas cms, sabemos que existe cms_page lidar).Então não posso confiar neste método

2.Use um observador

O segundo método seria ouvir um observador apropriado.Novamente, não consigo encontrar um observador baseado em bloco estático que seja acionado durante o tempo de carregamento do layout/bloco.No entanto, existem alguns observadores gerais em quem posso confiar.Eu penso controller_action_layout_generate_blocks_before pode usar no meu caso.Mas aqui estou eu enfrentando meu verdadeiro problema

Meu verdadeiro problema

Então quando eu uso controller_action_layout_generate_blocks_before evento no meu caso, o problema é que não consigo recuperar blocos com base em seu tipo.Posso filtrar blocos com base em seus name, mas não com base em seus type.ou seja

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

Na verdade, não posso confiar em nomes. Porque eu quero pegar tudo cms/block digite blocos e adicione um novo modelo depois de verificar algumas de suas propriedades personalizadas que defini com bloco estático

Então, como posso obter tudo cms/block através de um observador?É mesmo possível.Por favor, compartilhe seus pensamentos.

Foi útil?

Solução

Usa isto:

           <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>

Observador:

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

Referir-se protected function _toHtml() do Mage_Cms_Block_Block se você quiser fazer algumas alterações.

Atualização (outra solução)

    <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>

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

Outras dicas

Você não poderia simplesmente ouvir o evento core_block_abstract_to_html_before então verifique o tipo de bloco no evento e atualize o modelo com base nisso?Algo como o seguinte deve bastar.

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

Isso funcionaria para todos os blocos, mas se você sabe que isso só acontece em alguns casos, sugiro alterar o modelo via layout xml.

Ou se você quiser acrescentar algo a um bloco, mas deixar o original como está, você pode usar o core_block_abstract_to_html_after pegue o transport passou para o evento.Em seguida, coloque o html em relação a isso e anexe o que você precisa.Novamente, este evento fornece o bloco para que você possa limitar seu código de maneira simples 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);
}

Pelo que me lembro, você pode obter todos os blocos como uma coleção ou como uma matriz do layout e, em seguida, verificar seu tipo usando o operador "instância de".

Licenciado em: CC-BY-SA com atribuição
Não afiliado a magento.stackexchange
scroll top