,

Url Rewriting et Symfony : Fantastique !

URL Rewriting Symfony

Comme je l’ai expliqué précédemment, l’url rewriting est important, mais ce n’est pas toujours aisé à mettre en place, encore une fois Symfony va nous simplifier la vie, qui utilise en natif l’url rewriting de niveau 1, mais qui permet surtout une manipulation très simple de celui de niveau 2.

Url Rewriting par défaut

Par défaut Symfony utilise des url correspondant au module et à l’action en cours, ce qui donne pour la visualisation de l’article 55 :

http://www.monsite.com/article/show/id/55

Les variables sont automatiquement transformées : ?id=55 devenant /id/55

Les liens ressemblant ainsi à :

echo link_to ( « show », ‘article/show?id=’.$article->getId() )

Ce choix d’url rewriting est configuré par défaut dans le fichier /fo/config/routing.yml :

# La page d’accueil redirige vers le module main et vers l’action index
homepage:
    url:   /
    param: { module: main, action: index }
# Pour chaque index de module redirige vers l’action index
default_index:
    url:   /:module
    param: { action: index }
# Pour chaque module et chaque action redirige vers l’action correspondante
default:
    url:   /:module/:action/*

Url Rewriting totalement contrôlé

Mais voilà pour le référencement le niveau 2 est tout de même beaucoup plus intéressant, et Symfony est très bon à ce petit jeu.

Imaginons que nous ayons des rubriques et des articles, nous souhaitons des urls de type http://www.monsite.com/url-ma-rubrique/url-mon-article/ , les informations d’url étant tirés de la base de donnée et sans masque d’url (ex : rubrique-url-ma-rubrique/article-url-mon-article/), ce qui est trop facile.

Tout d’abord nous devons ajouter cette nouvelle configuration au début du fichier routing.yml :

 # Si j’ai le masque avec une url de type rubrique (rurl) et une de type article (aurl),
# je redirige vers l’action permalink du module article
article_by_aurl:
    url: /:rurl/:aurl
    param: { module: article, action: permalink }
# Redirige vers l’action index du module article avec comme variable id
article_by_id:
    url:  /article/index/id/:id
    param: { module: article, action: index }

rubrique_by_rurl:
    url:  /:rurl
     param: { module: main, action: permalink }

rubrique_by_id:
    url:  /main/index/id/:id
    param: { module: main, action: index }


Ensuite je dois créer ces 2 nouvelles actions Permalink dans chacune des classes actions des modules.

# Function à ajouter dans la classe /fo/module/rubrique/actions/actions.class.php
public function executePermalink() {

  # Vérifie qu’il existe bien une rubrique en ligne, sinon Erreur 404
  $rurl = $this->getRequestParameter('rurl') ;
  $c = new Criteria();
  $c->add( RubriquePeer::URL,$rurl );
  $c->add( RubriquePeer::EN_LIGNE , 1 );
  $rubrique = RubriquePeer::doSelectOne($c);
  $this->forward404Unless($rubrique) ;


  # Vérifie qu’il existe bien au moins un article en ligne pour cette rubrique,
  # sinon Erreur 404
  $c = new Criteria();
  $c->add( ArticlePeer::RUBRIQUE_ID, $rubrique->getId() );
  $c->add( ArticlePeer::EN_LIGNE , 1 );
  $cArticle = ArticlePeer::doCount($c);
  $this->forward404If($cArticle < 1) ;

  # Si tout ok, passe au module main et à l’action index avec la variable id
  $this->getRequest()->setParameter('id', $rubrique->getId());
  $this->forward(main, 'index');
}


# Function à ajouter dans la classe /fo/module/article/actions/actions.class.php
public function executePermalink()   {

  # Imaginons que toutes les rubriques sont en session pour éviter les accès à la base
  $allRubriques = sfContext::getInstance()->getUser()->getAttribute('allRubriques');

  # on vérifie qu’il existe bien une rubrique correspondant à la variable $rurl
  # sinon Erreur 404
  $rurl = $this->getRequestParameter('rurl') ;

  foreach($rzwRubrique as $rubrique) {
    if($rubrique->getUrl()== $rurl )
      $currentRubrique =  $rubrique;
    }
    $this->forward404Unless($currentRubrique);


    # on vérifie qu’il existe bien un article correspondant à la variable $aurl
    # sinon Erreur 404
    $aurl = $this->getRequestParameter('aurl') ;
    $c = new Criteria();
    $c->add( ArticlePeer::URL, $aurl );
    $c->add( ArticlePeer::RUBRIQUE_ID, $currentRubrique ->getId() );
    $c->add( ArticlePeer::EN_LIGNE , 1 );
    $article = ArticlePeer::doSelectOne($c);
    $this->forward404Unless($article);

    # Si tout ok, passe au module article et à l’action show avec la variable id
    $this->getRequest()->setParameter('id', $article->getId() );
    $this->forward('article', 'show');
}

à voir aussi...


9 Commentaires

Parlons ensemble...

Commenter ce billet, mais ATTENTION, tout commentaire "spammy" sera supprimé ("Génial" n'est pas un commentaire), ne suroptimisez pas non plus vos textes d'ancrages ("rencontre paris" n'est pas un pseudo).

*Obligatoire

Les widgets c'est laids ↓ et cela alourdit les pages, alors on les cachent en bas
Google Analytics Alternative