Ajouter ou ignorer un block depuis un module

  • De le 22 septembre 2009
  • Difficulté : 3/4

Ajouter ou ignorer un block depuis un module Peut être auriez vous besoin, lors du développement d'un module, de supprimer ou d'ajouter un block de façon automatique (par exemple un tag), sans pour autant éditer les fichiers XML des layouts...

Pour ajouter ou ignorer un block depuis un module, il faut utiliser les observers. L'événement (event) qui nous intéresse se nomme controller_action_layout_generate_blocks_before. Cet événement correspond à l'instant où Magento s'apprête à générer les blocks déclarés depuis les fichiers xml. L'objet de la classe Mage_Core_Model_Layout récupéré depuis l'observer contient donc l'ensemble des éléments que composent le layout. Exemple :

Mage_Core_Model_Layout Object

[9] => Mage_Core_Model_Layout_Element Object
   (
      [@attributes] => Array
         (
            [type] => page/html_footer
            [name] => footer
            [as] => footer
            [template] => page/html/footer.phtml
         )

      [block] => Array
         (
            [0] => Mage_Core_Model_Layout_Element Object
               (
                  [@attributes] => Array
                     (
                        [type] => page/template_links
                        [name] => footer_links
                        [as] => footer_links
                        [template] => page/template/links.phtml
                     )
               )
         )
   )

Nous sommes donc en mesure de supprimer ou ajouter des blocks avant qu'ils ne soient générées.

Nous allons créer un module qui se chargera dans un premier temps de supprimer un block existant, puis d'en générer un nouveau.

Architecture du module

  • app/code/local/Magentix/EditLayout/Block/
  • Text.php
  • app/code/local/Magentix/EditLayout/etc/
  • config.xml
  • app/code/local/Magentix/EditLayout/Model/
  • Observer.php

Développement du module

Éditons pour commencer le fichier de configuration afin de déclarer un nouveau block et d'ajouter un observer sur l'event controller_action_layout_generate_blocks_before qui exécutera la méthode edit_layout :

app/code/local/Magentix/EditLayout/etc/config.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Magentix_EditLayout>
            <version>0.1</version>
        </Magentix_EditLayout>
    </modules>
    <global>
        <blocks>
              <magentix_editlayout>
                  <class>Magentix_EditLayout_Block</class>
              </magentix_editlayout>
        </blocks>
        <models>
              <editlayout>
                  <class>Magentix_EditLayout_Model</class>
              </editlayout>
        </models>
     </global>
     <frontend>
        <events>
            <controller_action_layout_generate_blocks_before>
                <observers>
                    <magentix_editlayout_observer>
                        <type>singleton</type>
                        <class>editlayout/observer</class>
                        <method>edit_layout</method>
                    </magentix_editlayout_observer>
                </observers>
            </controller_action_layout_generate_blocks_before>
        </events>
     </frontend>
</config>

Éditons ensuite notre block de type magentix_editlayout/text. Ce block affichera tout simplement un texte quelconque...

app/code/local/Magentix/EditLayout/Block/Text.php

<?php

class Magentix_EditLayout_Block_Text extends Mage_Core_Block_Text {
        
        public function getText() {
                $html = 'Mon texte';
                return $html;
        }
        
        protected function _toHtml() {
                $this->addText($this->getText());
                return parent::_toHtml();
        }
        
}

C'est enfin la méthode edit_layout de l'observer qui récupérera l'objet de la classe Mage_Core_Model_Layout afin d'y apporter quelques modifications. Dans cet exemple, on ignore d'abord le block footer_links, puis on ajoute notre nouveau block, enfant du block footer. Les liens du footer seront donc remplacés par le texte issue du nouveau block...

app/code/local/Magentix/EditLayout/Model/Observer.php

<?php

class Magentix_EditLayout_Model_Observer {

        public function edit_layout($observer) {
                $layout = $observer->getLayout();
                
                $footer = $layout->getXpath("//block[@name='footer']");
                $footerLinks = $layout->getXpath("//block[@name='footer_links']");
                
                if (!$footer || !$footerLinks) return $this;
                
                $footerLinks[0]->addAttribute('ignore', true);

                $block = $footer[0]->addChild('block');
                $block->addAttribute('type', 'magentix_editlayout/text');
                $block->addAttribute('name', 'editlayout_text');
                $block->addAttribute('as', 'editlayout_text');

                return $this;
        }
        
}
commentaires

Commentez cet article : Ajouter ou ignorer un block depuis un module