ブロックが存在するかどうかを確認する方法(そのタイプに基づいて)
-
11-12-2019 - |
質問
これは本当に私を混乱させます!!
私は新しいブロックを作成する必要がある状況に来ました(core/template
ページレイアウトにCMSブロックが存在する場合は、プログラムでブロックします。一般的なケースでは、私の知る限り、これには2つの回避策があります。
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
静的ブロックで設定したカスタムプロパティのいくつかを確認した後、blocksと入力して新しいテンプレートを追加します
どのように私はすべてを得ることができますか 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>
オブザーバー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);
}
私が覚えている限り、すべてのブロックをコレクションまたはレイアウトから配列として取得し、「インスタンス」演算子を使用してタイプをチェッ