Sviluppare un'estensione in Contao - Terza parte

08/01/2011 22:16

Questa è la traduzione del tutorial Create a custom Contao module.
Per errori nella traduzione o incomprensioni della guida, contattatemi nel forum dove mi trovate con il nickname paplo.

Il modulo frontend per il sito

Ora, che la nostra sezione del backend è pronta, possiamo creare un modulo frontend che mostrerà la nostra collezione di CD sul sito.



Prima di cominciare, voglio ricordare che il modulo frontend di solito consiste in un file .php nella directory principale del modulo e in un file .tpl nella directory /templates.

Contao non è costruito seguento il pattern MVC tipico, ma mescolando il controller e il model. Quindi possiamo dire che i file .php nella directory /cd_collection sono una sorta di ibrido. Essi sono utilizzati per prelevare i dati dal database, analizzarli e passarli alle view, che vengono memorizzate nella cartella /templates.



In questo tutorial svilupperemo un semplice elenco di cd. Non divideremo la collezione di CD nei moduli Reader e Listing (come per le news). Tuttavia, dopo aver terminato la lettura di questa guida, sarete in grado di estendere il nostro modulo in queste due parti.

Ok, andiamo al lavoro.

Struttura dei file

Prima di tutto, creiamo i due file:

  1. /ModuleCdCollection.php (nella directory root del modulo)
  2. /Templates/mod_cdcollection.tpl

Non c'è molto da spiegare, quindi cerchiamo di scrivere il codice.

ModuleCdCollection.php

Nella prima parte, abbiamo deciso nel config.php che il nostro modulo di interfaccia userà la classe ModuleCdCollection:
// Front end module
array_insert($GLOBALS['FE_MOD']['miscellaneous'], 0, array
(
 'cd_collection' => 'ModuleCdCollection'
));
Si tratta di una buona convenzione scegliere come nome del file il nome della classe. Come già accade in altri framework PHP.

Ora aprite il file ModuleCdCollection.php e inserite il codice seguente:
<?php

class ModuleCdCollection extends Module
{

  protected $strTemplate = 'mod_cdcollection';

  protected function compile()
  {
    //
  }

}

?>
Come potete vedere abbiamo creato la classe ModuleCdCollection che estende Module. La classe Module fornisce due funzioni uniche e una variabile unica. La variabile protected $strTemplate definisce il template che verrà utilizzato dal modulo. Notate che non abbiamo incluso il percorso del file, perchè Contao utilizza module_root/templates come percorso predefinito.

Le uniche due funzioni sono compile() e generate(). Queste possono essere suddivise in frontend, compile(), e in backend, generate(). Noi in realtà non abbiamo bisogno della funzione generate() perchè visualizzeremo la raccolta di CD solo nel frontend (Contao è in grado di visualizzare un modulo nel backend utilizzando il DCA).

Ora, viene la parte più interessante dello sviluppo di un modulo - il seguente codice:
protected function compile()
{
  $intCategory = ($this->Input->get('cat')) ? $this->Input->get('cat') : 1;
  $arrCds = array();

  $objCds = $this->Database->prepare("SELECT * FROM tl_cds WHERE pid=? ORDER BY title")->execute($intCategory);
  $objCategory = $this->Database->prepare("SELECT * FROM tl_cds_category WHERE id=?")->execute($intCategory);
  $objCategories = $this->Database->execute("SELECT id, title FROM tl_cds_category ORDER BY title");

  while ($objCds->next())
  {
    $arrCds[] = array
    (
      'title' => $objCds->title,
      'artist' => $objCds->artist,
      'comment' => $objCds->comment,
      'src' => $objCds->image,
      'alt' => $objCds->title
    );
  }

  while ($objCategories->next())
  {
    $blnSelected = ($objCategories->id == $intCategory) ? true : false;

    $arrCategories[] = array
    (
      'id' => $objCategories->id,
      'title' => $objCategories->title,
      'selected' => $blnSelected
    );
  }

  $this->Template->cds = $arrCds;
  $this->Template->categories = $arrCategories;
  $this->Template->catTitle = $objCategory->title;
  $this->Template->catDescription = $objCategory->description;
}
Vediamo cosa c'è scritto sopra. In primo luogo, recuperiamo la variabile $_GET['cat'], che dirà al nostro modulo quale categoria dovrebbe essere visualizzata. Se questa variabile non è impostata, visualizza automaticamente la prima categoria (id = 1).

Successivamente, esegue tre query al database: elenco dei cd della categoria attuale, i dati della categoria attuale, l'elenco completo delle categorie. L'elenco completo delle categorie verrà utilizzato per creare un menu a tendina, che permette di passare da una categoria ad un'altra.

Nel primo ciclo while(), si ottengono tutti i cd che vengono memorizzati in un array. $objCds->next() assicura di non omettere neanche un cd.

Nel secondo ciclo while(), facciamo la stessa cosa di prima, ma con le categorie. In questo caso segnaliamo anche quale voce del menu a tendina è attualmente selezionata.

Infine, assegniamo tutti i dati al template.

templates/mod_cdcollection.tpl

Ora che abbiamo creato il controller del nostro modulo, è il momento di creare la view. Apriamo il fle templates/mod_cdcollection.tpl e inseriamo il codice seguente:
<span>Choose the category:</span>

<form action="" method="GET">
<select name="cat">
  <?php foreach($this->categories as $category): ?>
    <option value="<?php echo $category['id']; ?>"<?php if ($category['selected']): ?> selected="selected"<?php endif; ?>><?php echo $category['title']; ?></option>
  <?php endforeach; ?>
</select>
<input type="submit" value="OK" />
</form>

<h3><?php echo $this->catTitle; ?></h3>
<?php echo $this->catDescription; ?>

<table border="0" cellpadding="4">
<?php foreach ($this->cds as $cd): ?>
  <tr>
    <td><img src="<?php echo $cd['src']; ?>" height="100" width="100" alt="<?php echo $cd['alt']; ?>" /></td>
    <td>
      <p><strong><?php echo $cd['title']; ?></strong> (<?php echo $cd['artist']; ?>)</p>
      <?php echo $cd['comment']; ?>
    </td>
  </tr>
<?php endforeach; ?>
</table>
Beh, questo codice potrebbe risultare poco leggibile, per cui vi consiglio di incollarlo nel vostro editor preferito.

In primo luogo, abbiamo creato un form che fornisce un menu a tendina con le categorie. Come valori del menu prendiamo l'id delle categorie e scegliamo come predefinita la categoria attuale.

Successivamente, visualizziamo il titolo e la descrizione della categoria.

Creiamo una tabella che contiene il nostro elenco di CD. Poi utilizziamo il ciclo foreach() che passa attraverso la nostra raccolta di CD. Spero che questo codice sia chiaro per voi.

Proviamo. Dovremmo visualizzare qualcosa di simile a questo:


Le etichette

Sebbene il nostro modulo funzioni già, potremmo renderlo più userfriendly nel backend. Quello che voglio dire è che potremmo cambiare, ad esempio, {title_legend} con "Titolo CD".

Creaiamo una nuova directory "it" nella cartella /languages. Quindi creiamo tre file chiamati tl_cds.php, tl_cds_category.php e modules.php.

Si noti che la convenzione di denominazione è la stessa della cartella /DCA.

Okay, apriamo il file languages/it/tl_cds.php e inseriamo il seguente codice:



<?php

/**
 * Fields
 */
$GLOBALS['TL_LANG']['tl_cds_category']['title']       = array('Title', 'Please enter the title of the category.'); // 1
$GLOBALS['TL_LANG']['tl_cds_category']['description'] = array('Description', 'Please enter the description of the category.'); // 2

/**
 * Legends
 */
$GLOBALS['TL_LANG']['tl_cds_category']['title_legend'] = 'Title and description'; // 3

/**
 * Buttons
 */
$GLOBALS['TL_LANG']['tl_cds_category']['new']    = array('New category', 'Create a new category'); // 4
$GLOBALS['TL_LANG']['tl_cds_category']['show']   = array('Category details', 'Show details of category ID %s'); // 5
$GLOBALS['TL_LANG']['tl_cds_category']['edit']   = array('Edit category', 'Edit category ID %s'); // 6
$GLOBALS['TL_LANG']['tl_cds_category']['copy']   = array('Copy category', 'Duplicate category ID %s'); // 7
$GLOBALS['TL_LANG']['tl_cds_category']['delete'] = array('Delete category', 'Delete category ID %s'); // 8

?>
Ho preparato uno screenshot per spiegare meglio ciò che si vede:



Ora una piccola spiegazione su dove potete trovare le variabili delle etichette.

I campi possono essere recuperati direttamente dal file DCA:

// Fields
  'fields' => array
  (
    'title' => array
    (
      'label'             => &$GLOBALS['TL_LANG']['tl_cds_category']['title'],
      'inputType'         => 'text',
      'search'            => true,
      'eval'              => array('mandatory'=>true, 'maxlength'=>64)
    ),
// ...
L'etichetta del campo è un array, il cui primo elemento contiene il titolo del campo, mentre il secondo contiene la descrizione (o spiegazione) del campo.

Le legende sono recuperate dall'array palettes:
// Palettes
'palettes' => array
(
  'default'                     => '{title_legend},title,description'
),
I bottono sono recuperati dall'array operations. Tuttavia, notate che c'è un'etichetta aggiuntiva:
$GLOBALS['TL_LANG']['tl_cds_category']['new']    = array('New category', 'Create a new category');
Questo pulsante non è definito nell'array DCA, ed è visibile se l'array config della tabella ha la proprietà "closed" impostata a true ("closed" => true).

Queste sono tutte le etichette di cui abbiamo bisogno per ora. Scriviamo il seguente codice nel file tl_cds.php:
<?php

/**
 * Fields
 */
$GLOBALS['TL_LANG']['tl_cds']['title']   = array('CD Title', 'Please enter the title of the CD.');
$GLOBALS['TL_LANG']['tl_cds']['artist']  = array('Artist', 'Please enter the author of the CD.');
$GLOBALS['TL_LANG']['tl_cds']['image']   = array('Cover image', 'Please choose the CD cover image.');
$GLOBALS['TL_LANG']['tl_cds']['comment'] = array('Comment', 'Please enter your comment about CD.');

/**
 * Legends
 */
$GLOBALS['TL_LANG']['tl_cds']['title_legend']   = 'Title and artist';
$GLOBALS['TL_LANG']['tl_cds']['image_legend']   = 'CD Cover';
$GLOBALS['TL_LANG']['tl_cds']['comment_legend'] = 'Comment';

/**
 * Buttons
 */
$GLOBALS['TL_LANG']['tl_cds']['new']    = array('New CD', 'Create a new CD');
$GLOBALS['TL_LANG']['tl_cds']['show']   = array('CD details', 'Show details of CD ID %s');
$GLOBALS['TL_LANG']['tl_cds']['edit']   = array('Edit CD', 'Edit CD ID %s');
$GLOBALS['TL_LANG']['tl_cds']['copy']   = array('Copy CD', 'Duplicate CD ID %s');
$GLOBALS['TL_LANG']['tl_cds']['delete'] = array('Delete CD', 'Delete CD ID %s');

?>
Il codice sopra è molto simile a quello precedente. Penso che non necessiti di alcuna spiegazione ulteriore.

Okay, abbiamo già ottenuto le etichette "interne" del form. Ora dobbiamo creare le etichette che saranno visualizzate nelle altre sezioni di Contao.

Apriamo il file languages/en/modules.php e scriviamo il seguente codice:
<?php

/**
 * Back end modules
 */
$GLOBALS['TL_LANG']['MOD']['cd_collection'] = array('CD Collection', 'Manage your CD collection.');

/**
 * Front end modules
 */
$GLOBALS['TL_LANG']['FMD']['cd_collection'] = array('CD Collection list', 'adds a list of cds to your page.');

?>
Invece di spiegare in dettaglio il codice, mi limiterò a mostrarvi l'immagine:

Protezione dei file

Come ultimo punto, voglio mostrarvi come proteggere i nostri file impedendo che vi si possa accedere direttamente. Questo metodo è usato in (quasi) tutti i file .php in Contao.

Apriamo tutti i file .php e sostituiamo il tag <?php con:
<?php if (!defined('TL_ROOT')) die('You can not access this file directly!');

Note finali

Congratulazioni! Hai appena creato il tuo primo modulo personalizzato per Contao! Mi auguro che la guida sia chiara. Vi ringrazio molto per l'attenzione. Alla prossima.

Tags

Torna indietro

Aggiungi un commento