URL Rewriting souple : les routes de CakePHP
CakePHP offre une réelle souplesse dans la gestion de l’URL Rewriting à condition d’utiliser des « routes » et de toujours définir les liens de la même façon.
Imaginons un catalogue de produits : nous créons une table « references », un Modèle « Reference » et un Contrôleur « ReferencesController ». Ce Contrôleur contient l’action « voir » qui prend en paramètre l’id d’une référence et affiche la fiche produit. L’url pour accéder à la fiche produit dont l’id est 5 : /references/voir/5.
Dans une Vue, par exemple la liste des produits, nous avons :
1 2 3 4 5 6 7 8 9 | foreach($references as $reference) { e( $html->link( $reference['Reference']['nom'], '/references/voir/'.$reference['Reference']['id'] ) ); } |
Nous aimerions une url plus élégante, par exemple : /produit/5. Or il n’existe pas de Contrôleur « ProduitsController », et il n’y a apparemment pas d’action définie. Nous définissons alors une « route » dans le fichier /config/routes.php :
1 2 3 4 5 6 7 | Router::connect( '/produit/*', array( 'controller' => 'references', 'action' => 'voir' ) ); |
Ainsi, toute url commençant par « produit/ » sera renvoyée sur l’action « voir » du Contrôleur ReferencesController, avec l’id en paramètre.
Nous changeons la vue qui liste les références :
1 2 3 4 5 6 7 8 9 | foreach($references as $reference) { e( $html->link( $reference['Reference']['nom'], '/produit/'.$reference['Reference']['id'] ) ); } |
Et nous finissons notre site en utilisant toujours ce type d’url pour pointer vers une fiche produit.
Maintenant, nous préférerions que l’url soit de la forme : /catalogue/reference/5. Nous changeons la route :
1 2 3 4 5 6 7 | Router::connect( '/catalogue/reference/*', array( 'controller' => 'references', 'action' => 'voir' ) ); |
Mais nous devons alors changer tous les liens de nos vues qui pointent vers une fiche produit !
La solution est de toujours définir un lien en passant en paramètre à la fonction link() non pas une chaine de caratère (l’url telle que nous la voulons au final) mais un tableau associatif comme suit :
1 2 3 4 5 6 7 8 9 10 11 12 13 | foreach($references as $reference) { e( $html->link( $reference['Reference']['nom'], array( 'controller' => 'references', 'action' => 'voir', $reference['Reference']['id'] ) ) ); } |
De cette façon, l’url affichée dans le lien en sortie reflètera toujours la route définie dans routes.php, quelle qu’elle soit.