Routing et requête
Nous avons déjà abordé la notion de routing.
Dans notre projet, c’est Symfony qui gère nos routes (i.e. nos “chemins d’URL”).
Par exemple, quand on se rend sur localhost:8080/, c’est Symfony qui grâce à nos annotations @Route
que c’est la méthode index
de notre HomeController
qui doit être exécuté.
Le but va être ici de faire une route et une méthode de controlleur pour nos pages d’articles de blog.
On voudrait donc une URL du type /articles/{id de l'article}
, ainsi /articles/1
nous emmènera sur la page de l’article
ayant l’id 1
dans la base de données et celui-ci n’existe pas, nous devrons avoir une erreur 404.
Petit exemple
Dans votre HelloController
, ajoutez la méthode suivante
/**
* @Route("/hello/{name}", name="hello_name")
*/
public function helloName()
{
return new Response("Hello !");
}
et ajoutez l’import use Symfony\Component\HttpFoundation\Response;
Essayez d’aller sur la page localhost:8080/hello/test.
Vous êtes aller sur /hello/john
et cela vous a ammener sur la page correspondant à /hello/{name}
.
C’est parce {name}
est un paramètre, mais comment le récupérer ?
1ère méthode : Avec l’objet Request
Modifiez votre code comme ceci
/**
* @Route("/hello/{name}", name="hello_name")
*/
public function helloName(Request $request)
{
return new Response('Hello ' . $request->get('name'));
}
et ajoutez l’import use Symfony\Component\HttpFoundation\Request;
Actualisez la page, vous devriez voir apparaître Hello john
.
C’est une première piste pour notre page d’article de blog.
2ème méthode : avec des paramètres de méthode
Changez à nouveau votre code par celui-ci
/**
* @Route("/hello/{name}", name="hello_name")
*/
public function helloName($name)
{
return new Response('Hello ' . $name);
}
Ici, comme votre route contient un paramètre name
, Symfony essaye de passer la valeur à un argument
de la méthode qui s’appelle $name
.
Encore mieux non ?
Appliquons ça à notre page article
Créez ArticleController
grâce à la commande php bin/console make:controller
Rennomez la méthode index
en show
et ajouter la route /articles/{id}
Récupérez l’id en utilisant la méthode que vous préfèrez.
Injectez le repository des articles dans ce nouveau controller et avec la méthode find($id)
, récupérez
l’article en base de données.
Dans le dossier templates/article
, rennommez également le index.html.twig
en show.html.twig
et adaptez
dans ce nouveau template le fichier post.html
du template que nous avions téléchargé au chapitre sur Twig.
Passez votre article au template et afficher les données de votre article dans cette nouvelle page.
Enfin, générez les liens vers les articles dans home/index.html.twig
avec la méthode url()
. Cherchez dans la documentation
comment vous pouvez passer un paramètre à cette méthode pour qu’elle génère l’URL avec l’id à l’intérieur.
Si tout va bien, vous pouvez aller sur la page d’accueil et cliquer sur un lien : vous devriez arriver sur lma page de détail d’un article !
Quelque chose ne va pas ?
A ce moment là, il se peut que votre page ne ressemble à rien ☹
C’est parce vos fichiers CSS sont chargés relativement à la nouvelle URL par votre navigateur et du coup, les URL vers les fichiers CSS, JS et les images ne sont pas bonnes.
Pour résoudre ça : composer require symfony/asset
Ce paquet va vous forunir une méthode Twig bien pratique : asset('path/to/my/file.css')
Avec cette méthode, pas besoin de se soucier de ce genre de problèmes, elle va géjnérer des URL absolues vers vos fichiers statiques.
Utilisez cette méthode pour tous vos fichiers CSS, JS et vos images.
Ce paquet peut faire beaucoup plus que ça, consulter la documentation si vous voulez en savoir plus.
Et maintenant, elle est belle votre page article ?
Normalement, vous devriez avoir une belle page article.
Mais on peut encore réduire le nombre de lignes dans notre controlleur grâce au ParamConverter !
D’abord, ajoutez le Bundle qui inclu le ParamConverter composer require sensio/framework-extra-bundle
Changez la signature de votre méthode par
/**
* @Route("/articles/{id}", name="show")
*/
public function show(Article $article)
Et supprimez dans le corps de la méthode l’appel au repository, pour ne laisser que le return $this->render(...)
Actualisez votre page Article, normalement, rien n’a changé.
Symfony a tout fait à votre place !
Il a pris le nom de votre paramètre (ici id
) et a été chercher un Article
(grâce au typage) qui possède un id
avec
comme valeur, celle contenue dans l’URL !
Donc si vous changez id
par test
dans l’annotation @Route
, ça ne marchera pas, car Article
ne possède pas de champ
test
.
Ici aussi, vous pouvez aller dans le Profiler pour regarder la requête SQL générée par Doctrine.