Créer une route avec des paramètres et leurs contraintes
Nous avons créé une route avec des paramètres, très bien. Mais si quelqu'un essaie d'atteindre l'
URL /blog/oaisd/aouish.oasidh, eh bien rien ne l'en empêche ! Et pourtant, « oaisd » n'est pas tellement une année valide !

La solution ? Les contraintes sur les paramètres.
Reprenons notre dernière route sdzblog_voir_slug :
Code : Autre1
2
3
| sdzblog_voir_slug:
pattern: /blog/{annee}/{slug}.{format}
defaults: { _controller: SdzBlogBundle:Blog:voirSlug } |
Nous voulons ne récupérer que les bonnes
URL où l'année vaut « 2010 » et non « oshidf », par exemple. Cette dernière devrait retourner une erreur 404 (page introuvable). Pour cela, il nous suffit qu'aucune route ne l'intercepte ; ainsi, le routeur arrivera à la fin du fichier sans aucune route correspondante et il déclenchera tout seul une erreur 404.
Comment faire pour que notre paramètre
{annee} n'intercepte pas « oshidf » ? C'est très simple :
Code : Autre1
2
3
4
5
6
| sdzblog_voir_slug:
pattern: /blog/{annee}/{slug}.{format}
defaults: { _controller: SdzBlogBundle:Blog:voirSlug }
requirements:
annee: \d{4}
format: html|xml |
Nous avons ajouté la section
requirements. Comme vous pouvez le voir, on utilise les expressions régulières pour déterminer les contraintes que doivent respecter les paramètres. Ici :
- \d{4} veut dire « quatre chiffres à la suite ». L'URL /blog/sdff/mon-weekend.html ne sera donc pas interceptée. Vous l'avez reconnu, c'est une expression régulière. Vous pouvez utiliser n'importe laquelle, je vous invite à lire le cours correspondant de M@teo ;
- html|xml signifie « soit html, soit xml ». L'URL /blog/2011/mon-weekend.rss ne sera donc pas interceptée.
N'hésitez surtout pas à faire les tests ! Cette route est opérationnelle, nous avons créé l'action correspondante dans le contrôleur. Essayez donc de bien comprendre quels paramètres sont valides, lesquels ne le sont pas. Vous pouvez également changer la section "requirements".
Maintenant, nous souhaitons aller plus loin. En effet, si le « .xml » est utile pour récupérer l'article au format XML (pourquoi pas ?), le « .html » semble inutile : par défaut, le visiteur veut toujours du HTML. Il faut donc rendre le paramètre
{format} facultatif.
Utiliser des paramètres facultatifs
Reprenons notre route et ajoutons-y la possibilité à
{format} de ne pas être renseigné :
Code : Autre1
2
3
4
5
6
| sdzblog_voir_slug:
pattern: /blog/{annee}/{slug}.{format}
defaults: { _controller: SdzBlogBundle:Blog:voirSlug, format: html }
requirements:
annee: \d{4}
format: html|xml |
Nous avons juste rajouté une valeur par défaut dans le tableau
defaults :
format: html. C'est aussi simple que cela !
Ainsi, l'
URL /blog/2011/mon-weekend sera bien interceptée et le paramètre
format sera mis à sa valeur par défaut, à savoir « html ». Au niveau du contrôleur, rien ne change : vous gardez l'argument
<?php $format comme avant et celui-ci vaudra « html ».
Utiliser des « paramètres système »
Prenons l'exemple de notre paramètre
{format} : lorsqu'il vaut « xml », vous allez afficher du XML et devrez donc envoyer le
header avec le bon « Content-type ». Les développeurs de Symfony2 ont pensé à nous et prévu des « paramètres système ». Ils s'utilisent exactement comme des paramètres classiques, mais effectuent automatiquement des actions supplémentaires :
- le paramètre {_format} : lorsqu'il est utilisé (comme notre paramètre {format}, rajoutez juste un underscore), alors un header avec le « Content-type » correspondant est envoyé. Exemple : vous appelez /blog/2011/mon-weekend.xml et le routeur va dire à l'objet Request que l'utilisateur demande du XML. Ainsi, l'objet Response enverra un header « Content-type: application/xml ». Vous n'avez plus à vous en soucier !
Depuis le contrôleur, vous pouvez récupérer ce format soit avec l'argument $_format comme n'importe quel autre argument, soit via la méthode getRequestFormat() de l'objet Request. Par exemple : <?php $this->get('request')->getRequestFormat() ;
- le paramètre {_locale} : lorsqu'il est utilisé, il va définir la langue dans laquelle l'utilisateur souhaite obtenir la page. Ainsi, si vous avez défini des fichiers de traduction ou si vous employez des bundles qui en utilisent, alors les traductions dans la langue du paramètre {_locale} seront chargées. Pensez à mettre un requirements: sur la valeur de ce paramètre pour éviter que vos utilisateurs ne demandent le russe alors que votre site n'est que bilingue français-anglais.
Ajouter un préfixe lors de l'import de nos routes
Vous avez remarqué que nous avons mis
/blog au début du
pattern de chacune de nos routes. En effet, on crée un blog, on aimerait donc que toutes les
URL aient ce préfixe
/blog. Au lieu de les répéter à chaque fois, Symfony2 vous propose de rajouter un préfixe lors de l'import du fichier de notre
bundle.
Modifiez donc le fichier
app/config/routing.yml comme suit :
Code : Autre1
2
3
| SdzBlogBundle:
resource: "@SdzBlogBundle/Resources/config/routing.yml"
prefix: /blog |
Vous pouvez ainsi enlever la partie
/blog de chacune de vos routes. Bonus : si un jour vous souhaitez changer
/blog par
/blogdemichel, vous n'aurez qu'à modifier une seule ligne.
