Come creare un modulo in Magento 1, parte 2

In un precedente articolo abbiamo mostrato quali sono gli step da eseguire per implementare un semplice modulo che stampa la frase “Hello World!” su una pagina del proprio store Magento.

In realtà abbiamo visto solo le fasi iniziali dello sviluppo di un modulo, nello specifico le attività riguardanti la sua registrazione, la sua configurazione di base e la generazione dei controller che si sono occupati di stampare le frasi desiderate sulle pagine web del sito.

Magento adotta, tra i vari, il design pattern MVC (Model-View-Controller) e, come da direttive quindi, non spetta al controller occuparsi della resa grafica.

In effetti, se proviamo a leggere il codice sorgente delle pagine web precedentemente create, vediamo che le frasi stampate dalla nostra istruzione ‘echo’ sono addirittura fuori dal documento HTML delle pagine stesse. Questo proprio perché non sono entrate nel meccanismo di layout di Magento.

Chi si occupa della componente ‘View’ in Magento sono i blocchi (blocks).

Andiamo quindi subito ad eliminare i tentativi di stampa dai nostri controller; cancelliamo la riga

echo 'Hello World from New Controller!';

dal file <base_dir>/app/code/local/WaPoNe/Helloworld/controllers/NewController.php e la riga

echo 'Hello World!';

dal file <base_dir>/app/code/local/WaPoNe/Helloworld/controllers/IndexController.php

Abbiamo quindi ora entrambi i controller che si occupano semplicemente di chiamare il meccanismo di design in Magento, tramite le righe di codice:

$this->loadLayout();

$this->renderLayout();

Chiarito questo punto estremamente importante per un sviluppo corretto dei moduli in Magento, in questo articolo proviamo a rendere il modulo più completo, concentrandoci sulla parte di ‘View’, studiando i blocchi, i layout ed i template.

Partiamo dal vedere come personalizzare il frontend del modulo WaPoNe_Helloworld tramite il caricamento di un file XML di layout.

Per fare questo è necessario apportare delle modifiche al file di configurazione del modulo aprendo con un editor il file <base_dir>/app/code/local/WaPoNe/Helloworld/etc/config.xml (vedi precedente articolo) e all’interno del tag <frontend>, dopo la dichiarazione di <routers> e al suo stesso livello, aggiungiamo:

<layout>
  <updates>
   <helloworld>
    <file>wapone/helloworld.xml</file>
   </helloworld>
 </updates>
</layout>

inoltre prepariamo il file di layout helloworld.xml nella cartella del nostro tema <base_dir>/app/design/frontend/<package>/<theme>/layout/wapone/ (nel caso di un’installazione base di Magento <package> è ‘default’ così come anche theme, come da immagine)

creare-un-modulo-in-magento-1-parte-2

e in esso scriviamo:

<?xml version="1.0" encoding="UTF-8"?>
<layout>
  <helloworld_new_hello>
    <reference name="root">
      <action method="setTemplate">
        <template>page/2columns-right.phtml</template>
      </action>
    </reference>
  </helloworld_new_hello>
</layout>

Ci siamo limitati, per l’”handle” <helloworld_new_hello> a caricare il template di pagina 2columns-right.phtml contenuto all’interno della directory <base_dir>/app/design/frontend/base/default/template/page/ (installazione pulita di Magento).

Soffermandoci sulla nomenclatura dell’handle, vale la regola spiegata nello scorso articolo: <moduleName o frontName>_<controllerName>_<actionName>

Se proviamo quindi a ricaricare la nostra web page all’indirizzo: http://nomesito.estensione/helloworld/new/hello

notiamo subito la mancanza dei blocchi sulla parte sinistra del sito, proprio perché il template che abbiamo impostato non prevede come output la colonna sinistra.

creare-un-modulo-in-magento-1-parte-2

Cominciamo ora a personalizzare la nostra pagina. Visualizzando il contenuto del file template 2columns-right.phtml è possibile notare che esso si dedica alla generazione del documento HTML, effettuando chiamate a vari componenti (reference) come, per esempio, il ”reference” ‘content’ tramite l’istruzione <?php echo $this->getChildHtml(‘content’) ?>, che nel nostro caso (per la nostra pagina) è ancora vuoto, non ha contenuto.

Per questo motivo generiamo un blocco con lo scopo di popolare la porzione ‘content’ della nostra web page.

Per fare questo dobbiamo prima registare il blocco nel file <base_dir>/app/code/local/WaPoNe/Helloworld/etc/config.xml del modulo, aggiungendo il seguente pezzo di codice xml all’interno del tag <config>:

<global>
  <blocks>
    <helloworld>
      <class>WaPoNe_Helloworld_Block</class>
    </helloworld>
  </blocks>
</global>

Fatto questo, possiamo creare il file Hello.php che gestisce il nostro blocco all’interno della cartella <base_dir>/app/code/local/WaPoNe/Helloworld/Block/:

<?php

class WaPoNe_Helloworld_Block_Hello extends Mage_Core_Block_Template
{
    $hello = "Hello World!";
}

Attenzione: il nome del file deve coincidere con il nome della classe del blocco; nell’esempio Hello.php e WaPoNe_Helloworld_Block_Hello

Il passaggio finale prevede la definizione del file di template che si occupa del design della pagina. Torniamo nel file di layout <base_dir>/app/design/frontend/<package>/<theme>/layout/wapone/helloworld.xml ed aggiungiamo l’istruzione che associa il blocco alla reference ‘content’:

<reference name="content">
  <block type="helloworld/hello" name="block_hello" template="wapone/hello.phtml" />
</reference>

nel tag <helloworld_new_hello>.

Il risultato finale del nostro file di layout helloworld.xml è:

<?xml version="1.0" encoding="UTF-8"?>
<layout>
  <helloworld_new_hello>
    <reference name="root">
      <action method="setTemplate">
        <template>page/2columns-right.phtml</template>
      </action>
    </reference>
    <reference name="content">
      <block type="helloworld/hello" name="block_hello" template="wapone/hello.phtml" />
    </reference>
 </helloworld_new_hello>
</layout>

Cosa significano le ultime righe inserite riguardanti il blocco del modulo?

In ‘type’ viene inserita la classe del blocco seguendo la nomenclatura di Magento, si definisce un ‘name’ e si lega al blocco un ‘template’ che viene cercato a partire dalla directory del tema. Andiamo a crearlo, nel caso del nostro esempio, in <base_dir>/app/design/frontend/default/default/template/wapone/ e lo chiamiamo hello.phtml, come definito nel file di layout. E’ qui che il web designer può dare sfogo alla propria fantasia; per il nostro scopo può bastare qualcosa del tipo:

<p><?php echo $this->hello ?></p>

Da notare che nel template viene richiamata la variabile hello (istanziata nella classe del blocco) grazie a $this perché Magento in fase di rendering del layout include il template nel blocco.

Carichiamo nuovamente la pagina web e questa volta il content è popolato dal contenuto della variabile hello:

creare-un-modulo-in-magento-1-parte-2-iii

Ottimo!

Adesso il nostro primo modulo, che si occupa di stampare una frase su una pagina dell’e-commerce, funziona correttamente rispettando i criteri imposti dal pattern MVC.

Ma prendiamo ulteriore dimestichezza con il framework Magento e complichiamo l’esempio; lo facciamo usando l’altra action controller definita nello scorso articolo: <helloworld><index><index>

Supponiamo volessimo stampare in questa pagina gli ultimi cinque prodotti inseriti sullo store.

Andiamo a creare il blocco che si occupa di estrapolare i prodotti; di nuovo in <base_dir>/app/code/local/WaPoNe/Helloworld/Block/ aggiungiamo il file Newproducts.php così fatto:

<?php


class WaPoNe_Helloworld_Block_Newproducts extends Mage_Core_Block_Template
{
  public function getProducts()
  {
    $products = Mage::getModel('catalog/product')->getCollection()
      ->addAttributeToSelect('*')
      ->setOrder('created_at')
      ->setPageSize(5);

    return $products;
  }
}

Per compiere questa attività si è fatto ricorso ad un altro componente importante di Magento: le collection. Anche se le collection non sono argomento di questo articolo, è facilmente intuibile il loro scopo e utilizzo; in questo caso semplicemente si è richiesta una lista di prodotti, caricando tutti gli attributi a loro collegati (addAttributeToSelect(‘*’)), ordinandola per data di creazione dei prodotti (setOrder(‘created_at’)) e filtrandola per estrarne solo cinque (setPageSize(5)).

Ora è necessario definire nel file di layout la gestione del nuovo “handle” che è <helloworld_index_index>. Apriamo nuovamente il file di layout del modulo <base_dir>/app/design/frontend/<package>/<theme>/layout/wapone/helloworld.xml e aggiungiamo nel tag <layout> il nuovo “handle”, esattamente come già fatto per < helloworld_new_hello>, provando a caricare questa volta un template di pagina differente, 2columns-left.phtml:

<helloworld_index_index>
  <reference name="root">
    <action method="setTemplate">
     <template>page/2columns-left.phtml</template>
   </action>
 </reference>
 <reference name="content">
   <block type="helloworld/newproducts" name="block_newproducts" template="wapone/newproducts.phtml" />
 </reference>
</helloworld_index_index>

Quello che manca per vedere la lista dei prodotti è il file template che generiamo sempre in <base_dir>/app/design/frontend/default/default/template/wapone/ e che nominiamo newproducts.phtml come definito. Il suo contenuto è:

<h2>New Products</h2>
<ul>
  <?php foreach ($this->getProducts() as $_product): ?>
    <li><?php echo $_product->getName() ?></li>
 <?php endforeach; ?>
</ul>

Avviamo il nostro browser preferito e digitiamo l’indirizzo web: http://nomesito.estensione/helloworld/index/index o più semplicemente http://nomesito.estensione/helloworld per visualizzare il risultato desiderato:

creare-un-modulo-in-magento-1-parte-2-v

Conclusione

L’obiettivo di questo articolo, sulla base del suo precedente, è stato mostrare come completare la creazione di un modulo rispettando le direttive imposte dai design pattern utilizzati da Magento, come MVC. Ci siamo quindi concentrati sulla parte di View del modulo, spiegando il ruolo dei componenti della presentazione in Magento quali blocchi, layout e template. Volutamente non sono state affrontate tematiche legate all’implementazione della logica di business di un modulo.

Categoria: