Come controllare se esista un blocco (in base al suo tipo)
-
11-12-2019 - |
Domanda
Questo mi confonde davvero !!
Sono arrivato a una situazione, dove ho bisogno di creare un nuovo blocco (blocco core/template
) a livello di programmazione, se c'è un blocco CMS presente in un layout di pagina. In generale, secondo le mie conoscenze, ci sono due lavori per questo.
1. Aggiungi un blocco tramite layout
Nella maggior parte del caso, questa sarebbe la migliore idea di fare questo compito. Siamo in grado di aggiungere un blocco a una pagina se è disponibile una maniglia di layout appropriata. Ma sfortunatamente, nel mio caso, non ho alcuna maniglia di layout specifica del blocco statico disponibile (per le pagine CMS, sappiamo che c'è una maniglia cms_page
). Quindi non posso fare affidamento su questo metodo
2. Utilizzare un osservatore
Il secondo metodo sarebbe ascoltare un osservatore appropriato. Ancora una volta, non riesco a trovare un osservatore basato su blocco statico che viene attivato durante il layout / tempo di caricamento del blocco. Tuttavia ci sono alcuni osservatori generali su cui posso fare affidamento. Penso che il controller_action_layout_generate_blocks_before
possa usare nel mio caso. Ma qui sto affrontando il mio vero problema
Il mio vero problema
Quindi quando utilizzo l'evento controller_action_layout_generate_blocks_before
nel mio caso, il problema è che, non riesco a recuperare i blocchi in base al loro tipo. Posso filtrare i blocchi in base al loro name
, ma non basato sul loro type
. IE
$observer->getEvent()->getLayout()->getBlock('block_name'); //this work; Used name
$observer->getEvent()->getLayout()->getBlock('cms/block'); //this wont; use type
.
Non posso fare affidamento sui nomi in effetti. Perché voglio ottenere tutti i blocchi di tipo cms/block
e aggiungere un nuovo modello dopo aver controllato alcune delle proprie proprietà personalizzate che ho impostato con il blocco statico
Allora, come posso ottenere tutti i cms/block
attraverso un osservatore? È anche possibile. Si prega di condividere i tuoi pensieri.
controller_action_layout_generate_blocks_before
nel mio caso, il problema è che, non riesco a recuperare i blocchi in base al loro tipo. Posso filtrare i blocchi in base al loro name
, ma non basato sul loro type
. IE
$observer->getEvent()->getLayout()->getBlock('block_name'); //this work; Used name
$observer->getEvent()->getLayout()->getBlock('cms/block'); //this wont; use type
cms/block
e aggiungere un nuovo modello dopo aver controllato alcune delle proprie proprietà personalizzate che ho impostato con il blocco statico
cms/block
attraverso un osservatore? È anche possibile. Si prega di condividere i tuoi pensieri. Soluzione
Usa questo:
<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>
.
Observer:
public function generateBlocks($observer)
{
/**
* @var $block Mage_Core_Block_Abstract
*/
$block = $observer->getEvent()->getBlock();
if ($block->getType() == 'cms/block') {
//do something
}
}
.
Fare riferimento a protected function _toHtml()
del Mage_Cms_Block_Block
se si desidera effettuare alcune modifiche.
Aggiornamento (un'altra soluzione)
<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);
}
}
}
. Altri suggerimenti
Non è possibile semplicemente ascoltare l'evento core_block_abstract_to_html_before
, quindi controllare il tipo di blocco sull'evento e aggiornare il modello in base a questo?Qualcosa come il seguente dovrebbe farlo.
$block = $observer->getBlock();
if ($block instanceof Mage_Cms_Block_Block) {
// Make your changes here
}
.
Questo funzionerebbe per tutti i blocchi, ma se sai dire che questo succede solo in alcuni casi, suggerirei di cambiare il modello tramite layout XML.
O se si desidera aggiungere qualcosa a un blocco, ma lasciare all'originale come è possibile utilizzare il core_block_abstract_to_html_after
, ottenere il transport
superato l'evento.Quindi ottenere l'HTML impostato contro questo e aggiungi ciò di cui hai bisogno.Di nuovo questo evento ti dà il blocco in modo da poter limitare il tuo codice così semplicemente 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);
}
. Per quanto mi ricordo, puoi ottenere tutti i blocchi come una raccolta o come array dal layout un loop attraverso il controllo del loro tipo usando l'operatore "istanza di".