So überprüfen Sie, ob ein Block vorhanden ist (basierend auf seinem Typ)
-
11-12-2019 - |
Frage
Das verwirrt mich wirklich!!
Ich bin in eine Situation geraten, in der ich einen neuen Block erstellen muss (core/template
Block) programmgesteuert, wenn ein CMS-Block in einem Seitenlayout vorhanden ist.Im Allgemeinen gibt es meines Wissens nach zwei Lösungsmöglichkeiten dafür.
1.Fügen Sie einen Block über das Layout hinzu
In den meisten Fällen wäre dies die beste Idee, diese Aufgabe zu erledigen.Wir können einer Seite einen Block hinzufügen, wenn ein entsprechendes Layout-Handle verfügbar ist.Aber leider habe ich in meinem Fall kein spezifisches Layout-Handle für statische Blöcke zur Verfügung (für CMS-Seiten wissen wir, dass es eines gibt). cms_page
handhaben).Ich kann mich also nicht auf diese Methode verlassen
2.Benutzen Sie einen Beobachter
Die zweite Methode wäre, einem geeigneten Beobachter zuzuhören.Auch hier kann ich keinen statischen blockbasierten Beobachter finden, der während der Layout-/Blockladezeit ausgelöst wird.Es gibt jedoch einige allgemeine Beobachter, auf die ich mich verlassen kann.Ich finde controller_action_layout_generate_blocks_before
Kann in meinem Fall verwendet werden.Aber hier stehe ich vor meinem eigentlichen Problem
Mein eigentliches Problem
Also, wenn ich es benutze controller_action_layout_generate_blocks_before
In meinem Fall besteht das Problem darin, dass ich Blöcke nicht basierend auf ihrem Typ abrufen kann.Ich kann Blöcke anhand ihrer filtern name
, aber nicht auf der Grundlage ihrer type
.dh
$observer->getEvent()->getLayout()->getBlock('block_name'); //this work; Used name
$observer->getEvent()->getLayout()->getBlock('cms/block'); //this wont; use type
Ich kann mich tatsächlich nicht auf Namen verlassen. Weil ich alles bekommen will cms/block
Geben Sie Blöcke ein und fügen Sie eine neue Vorlage hinzu, nachdem Sie einige ihrer benutzerdefinierten Eigenschaften überprüft haben, die ich mit dem statischen Block festgelegt habe
Wie kann ich also alles bekommen? cms/block
durch einen Beobachter?Ist es überhaupt möglich.Bitte teilen Sie Ihre Gedanken mit.
Lösung
Benutze das:
<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>
Beobachter:
public function generateBlocks($observer)
{
/**
* @var $block Mage_Core_Block_Abstract
*/
$block = $observer->getEvent()->getBlock();
if ($block->getType() == 'cms/block') {
//do something
}
}
Beziehen auf protected function _toHtml()
des Mage_Cms_Block_Block
wenn Sie einige Änderungen vornehmen möchten.
Update (andere Lösung)
<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);
}
}
}
Andere Tipps
Könnte man der Veranstaltung nicht einfach zuhören? core_block_abstract_to_html_before
Überprüfen Sie dann den Blocktyp für das Ereignis und aktualisieren Sie die Vorlage auf dieser Grundlage.Etwas wie das Folgende sollte es tun.
$block = $observer->getBlock();
if ($block instanceof Mage_Cms_Block_Block) {
// Make your changes here
}
Dies würde für alle Blöcke funktionieren. Wenn Sie jedoch wissen, dass dies nur in einigen wenigen Fällen geschieht, würde ich vorschlagen, die Vorlage über Layout-XML zu ändern.
Oder wenn Sie etwas an einen Block anhängen, aber das Original so belassen möchten, können Sie das verwenden core_block_abstract_to_html_after
bekommen das transport
an die Veranstaltung übergeben.Stellen Sie dann den HTML-Code darauf ein und hängen Sie an, was Sie benötigen.Auch dieses Ereignis gibt Ihnen den Block, sodass Sie Ihren Code ganz einfach einschränken können 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);
}
Soweit ich mich erinnere, können Sie alle Blöcke als Sammlung oder als Array aus dem Layout abrufen und dann ihren Typ mit dem Operator „Instanz von“ überprüfen.