문제

이것은 정말로 나를 혼란스럽게합니다 !!

Page 레이아웃에 CMS 블록이있는 경우 프로그래밍 방식으로 새 블록 (core/template 블록)을 프로그래밍 방식으로 작성 해야하는 상황에 왔습니다. 일반적인 경우, 내 지식에 따르면, 이는 두 가지 작업이 있습니다.

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

관찰자 :

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

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

다른 팁

이벤트를 듣지 못할 수 없습니까? 그런 다음 이벤트의 블록 유형을 확인하고 이에 따라 템플릿을 업데이트하십시오.다음과 같은 것과 같아야합니다.

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

이것은 모든 블록에서 작동하지만, 이것이 몇 가지 인스턴스에서만 발생한다고 말하면 레이아웃 XML을 통해 템플릿을 변경하는 것이 좋습니다.

또는 블록에 무언가를 추가하지만 원래로 남겨두면 core_block_abstract_to_html_before를 사용할 수 있습니다. 이벤트에 전달 된 core_block_abstract_to_html_after를 가져올 수 있습니다.그런 다음 HTML을 설정하고 필요한 것을 추가하십시오.다시이 이벤트는 블록을 제공하므로 코드를 제한하여 단순히 transport

$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