Contents
Chapitre 6: Générer le module Game (II): Routing
Soyons clair: une URL pour la fiche du style frontend_dev.php/game/show/id/1 n’est pas tellement révélatrice. Aussi, nous allons aborder à présent le routing de base. Et commençons par le fichier routing.yml dans frontend/config.
Jobeet détaille tout détail par détail, moi, je vais droit au but. Vous êtes prévenu!
Homepage
Voici le fichier tel qu’il se présente.
# default rules homepage: url: / param: { module: default, action: index } # generic rules # please, remove them by adding more specific rules default_index: url: /:module param: { action: index } default: url: /:module/:action/*
La première chose que nous allons faire, c’est de changer homepage: nous allons lui indiquer quel module et quelle action seront notre page d’accueil: la liste de jeux.
homepage: url: / param: { module: game, action: index }
Ainsi, nous pourrons écrire directement http://localhost:9093/frontend_dev.php pour accéder à notre liste de jeux (auparavant, nous arrivions sur une page par défaut de symfony).
Occupons-nous ensuite de créer une route plus sympathique pour notre fiche individuelle:
game_show_game: url: /game/:id/:name_game class: sfDoctrineRoute options: model: game type: object param: module: game action: show requirements: id: \d+ sf_method: [get]
A quoi correspond chaque ligne?
games_show_game représente le nom de votre route.
url: /game/:id/:name_game peut être décodé ainsi: /module/:paramètre id (dont nous avons toujours besoin)/:nom du jeu (utiliser le nom de la colonne dans la db).
Le : indique qu’il s’agit d’un paramètre dont la valeur ne peut pas être mise en dur (comme le nom du module) et qu’elle est envoyée par l’objet.
class: sfDoctrineRoute représente la classe qui permet les routes représentées par des objets Doctrine (qui évitent donc d’écrire une URI interne trop longue).
options: {model: game, type: object} définit le modèle concerné par la route dans le cadre de sfDoctrineRoute.
param: {module: game, action: show} indique quel module est concerné et quelle action doit être exécutée.
requirements: {id: \d+, sf_method: [get]} indique les contraintes de la route: \d+ est mis par défaut pour permettre à ce que l’id soit du même type que celui de la base de données (pas une lettre par exemple). sf_method force un paramètre de type $_GET. Cela ne correspond pas à une méthode de récupération de paramètres uniquement $_GET comme sfWebRequest::isMethod().
Nous avons donc une url de type: http://localhost:9093/frontend_dev.php/game/2/Half-Life+2+Episode+Two
A présent, allons faire quelques changements dans les templates.
Les URLs dans les templates
Comme je vous l’ai déjà dit, nous avons des helpers pour permettre de coder vos urls sans les mettre telle quelles dans la template: url_for et link_to.
Allons donc dans la template indexSuccess.php pour changer les liens pour nos fiches:
<td><a href="<?php echo url_for('game_show_game', $game)?>"><?php echo $game->getNameGame() ?></a></td>
url_for se comprend ainsi dans notre cas: nom de la route suivi de l’objet envoyé. Sinon, vous pouvez envoyer une url de type module/action?param1=valeur1.
Ensuite, allons dans showSuccess.php pour remplacer le lien vers la liste par:
<a href="<?php echo url_for('@homepage') ?>">List</a>
Le @ indique que la route à prendre est celle-là, ainsi, il n’y a pas lieu d’analyser toutes les routes.
Améliorer l’URL de la fiche
Nous avons à présent une URL plus claire pour l’utilisateur. Néanmoins, le + est très gênant, surtout si l’URL est longue. Donc, nous allons les remplacer par des -. Comment? En créant une fonction slugify. Créons un fichier Videogames.class.php dans le dossier lib:
class Videogames { static public function slugify($text) { // replace all non letters or digits by - $text = preg_replace('/\W+/', '-', $text); // trim and lowercase $text = strtolower(trim($text, '-')); return $text; } }
Ensuite, ouvrons le fichier Game.class.php pour y ajouter ceci:
public function getNameGameSlug(){ return Videogames::slugify($this->getNameGame()); }
A présent, il ne nous reste plus qu’à modifier le paramètre url de notre route en ajoutant _slug derrière name_game:
game_show_game: url: /game/:id/:name_game_slug class: sfDoctrineRoute options: model: game type: object param: module: game action: show requirements: id: \d+ sf_method: [get]
Voici notre nouvelle URL: http://localhost:9093/frontend_dev.php/game/2/half-life-2-episode-two
Définitition d’une collection de la route pour un objet Doctrine
Nous avons personnalisé l’URL de l’action show mais pas les autres (new, edit, etc.). Bien sûr, elles sont générés mais il y a moyen de les configurer pour un besoin spécifique en utilisant la classe sfDoctrineRouteCollection:
game: class: sfDoctrineRouteCollection options: model: game
Si vous voulez voir ce que ce raccourci permet de générer, allez consulter le chapitre 5 du tutoriel Jobeet.
En attendant, vous pouvez mettre en commentaire default_index et default, ces routes sont devenues inutiles.
En savoir plus:
Routage avancé