블록이 있는지 확인하는 방법 (유형에 따라)
-
11-12-2019 - |
문제
이것은 정말로 나를 혼란스럽게합니다 !!
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
를 어떻게 얻을 수 있습니까? 그것은 또한 가능합니다. 당신의 생각을 공유하십시오.
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>
.
<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);
}
. 기억하는 한 컬렉션이나 레이아웃에서 모든 블록을 컬렉션으로 가져 오거나 배열로 루프를 "인스턴스의 인스턴스"를 사용하여 유형을 확인합니다.