martedì 3 novembre 2009

Lyra, elenco articoli per etichetta

Come si è visto nell'articolo precedente i link del menù Etichette hanno questo formato

article/label/id/x

Dove x è l'ID del record etichetta.

Dobbiamo scrivere il codice per l'azione label del modulo article ed il relativo template che determinerà l'aspetto della pagina con l'elenco degli articoli catalogati sotto una certa etichetta. L'elenco può naturalmente essere anche lungo quindi avremo bisogno di una funzione di paginazione, symfony ci mette a disposizione una classe dedicata a questo scopo.

apps/frontend/modules/article/actions/actions.class.php

class articleActions extends sfActions
{
...
  public function executeLabel(sfWebRequest $request)
  {
    $this->forward404Unless(
      $this->label = Doctrine::getTable('LyraLabel')
        ->find($request->getParameter('id'))
    );
    $this->pager = new sfDoctrinePager('LyraLabel', 25);
    $this->pager->setQuery($this->label->getItemsQuery());
    $this->pager->setPage($request->getParameter('page', 1));
    $this->pager->init();
  }
...
}
All'oggetto pager viene passata la query per la selezione degli articoli. Si imposta un valore costante (25) per il numero di record per pagina, in seguito questo parametro dovrà essere gestito dalla configurazione. La creazione della query avviene nel modello.
lib/model/doctrine/LyraLabel.class.php

class LyraLabel extends BaseLyraLabel
{
  public function getItemsQuery() {
    $q = Doctrine::getTable('LyraArticle')
      ->getActiveItemsQuery();

    $q->innerJoin($q->getRootAlias().'.ArticleLabels l')
      ->andWhere('l.id = ?', $this->getId());
    return $q;
  }
  ...
}

Interessante notare la sintassi DQL (Doctrine Query Language) usata per la query. Le tabelle articoli (articles, modello LyraArticle) ed etichette (labels, modello LyraLabel) sono tra loro in una relazione molti a molti tramite una tabella intermedia (article_label, modello LyraArticleLabel).

La relazione è definita in config/doctrine/schema.yml (vedere relations di LyraArticle) ed identificata come ArticleLabels: questo identificatore è l'unica informazione che passiamo al metodo innerJoin(), come si vede non ci sono clausole ON né nomi di tabelle in quanto tutte le informazioni necessarie a Doctrine per creare la query si trovano nello schema.

Veniamo al template labelSuccess.php.

apps/frontend/modules/article/templates/labelSuccess.php

<?php 
slot('page_title', $label->title);
...

Impostiamo uno slot per visualizzare il titolo della pagina. Con gli slot si può inserire del contenuto in zone predeterminate del layout.

...
include_partial('article/list', array('items'=>$pager->getResults()));
?>
<?php if ($pager->haveToPaginate()): ?>
  <?php 
    $base = 'article/label?id=' . $label->getId() . '&page=';
  ?>
  <div class="pagination">
    <?php echo link_to('First', $base . '1');?>
    <?php echo link_to('Prev', $base . $pager->getPreviousPage());?>
    <?php foreach ($pager->getLinks() as $page): ?>
      <?php if ($page == $pager->getPage()): ?>
        <?php echo $page ?>
      <?php else:
        echo link_to($page, $base . $page);
      endif; ?>
    <?php endforeach; ?>
    <?php echo link_to('Next', $base . $pager->getNextPage());?>
    <?php echo link_to('Last', $base . $pager->getLastPage());?>
  </div>
<?php endif; ?>
<!-- Fine  labelSuccess.php -->

Per la visualizzazione dell'elenco articoli riutilizziamo il partial creato per la prima pagina: di ogni articolo sarà visualizzato il titolo, la data e il sommario con link 'leggi tutto'. Il metodo getResults() dell'oggetto pager restituisce gli articoli da visualizzare in base al numero di pagina che abbiamo impostato nell'azione. La parte restante del template serve alla visualizzazione dei link per la paginazione.

Resta da aggiungere al layout l'istruzione per includere il contenuto dello slot impostato nel template.

Questa parte

apps/frontend/templates/layout.php
...
<div id="header">
  <h3>Titolo pagina</h3>
</div>
...

va modificata in questo modo

apps/frontend/templates/layout.php
...
<div id="header">
  <h3><?php include_slot('page_title'); ?></h3>
</div>
...

Tutto questo si trova nella revisione 17 su Google Code.

Nessun commento:

Posta un commento

Nota. Solo i membri di questo blog possono postare un commento.