Dans les articles précédents, nous avons créé la page affichant la liste des articles. Nous allons maintenant créer la page permettant d'afficher un seul article.
Afin d'accéder à l'article, nous allons utiliser son slug (version simplifiée de son titre) pour l'identifier dans l'URL.
Ainsil l'url d'un article intitulé "Les bases de Symfony" sera "/actualites/les-bases-de-symfony".
Nous verrons prochainement comment nous assurer que ce slug soit unique et généré automatiquement.
Le contrôleur
En attendant, nous allons modifier notre contrôleur "ArticlesController" et y créer la méthode permettant d'afficher un article.
Nous utiliserons une annotation avec un paramètre variable comme ci-dessous
/**
* @Route("/{slug}", name="article")
*/
Dans cette annotation, "{slug}" est la variable qui permettra d'avoir une route "dynamique".
Après avoir créé cette annotation, nous devons reprendre le paramètre en entrée de la méthode correspondante. Ici, nous allons créer la méthode "article" qui prendra le paramètre "slug", comme ci-dessous.
/**
* @Route("/{slug}", name="article")
*/
public function article($slug)
Maintenant que la méthode est créée, nous allons récupérer l'article ayant ce "slug" dans la base de données au moyen de la méthode "findOneBy" décrite précédemment.
Enfin, après avoir récupéré ces données, nous les envoyons à la vue que nous allons créer juste après.
Le contrôleur ressemblera à ceci.
/**
* @Route("/{slug}", name="article")
*/
public function article($slug){
// On récupère l'article correspondant au slug
$article = $this->getDoctrine()->getRepository(Articles::class)->findOneBy(['slug' => $slug]);
if(!$article){
// Si aucun article n'est trouvé, nous créons une exception
throw $this->createNotFoundException('L\'article n\'existe pas');
}
// Si l'article existe nous envoyons les données à la vue
return $this->render('articles/article.html.twig', compact('article'));
}
La vue
Nous allons maintenant créer le fichier "article.html.twig" afin d'afficher l'article.
Dans cette vue, nous avons reçu toutes les informations de l'article, ainsi que les informations liées comme les catégories et les mots-clés, par exemple.
Le fichier "article.html.twig" contiendra la structure de base de toutes nos pages, comme ceci
{% extends 'base.html.twig' %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}
Nous allons commencer par insérer le titre dans le bloc "title". La variable s'appelle "article" et la propriété s'appelle "titre", nous y accéderons donc par "article.titre" comme ceci.
{% block title %}{{ article.titre }}{% endblock %}
Nous allons structurer la page en affichant d'abord en haut le titre dans une balise h1, en dessous nous afficherons la date, puis enfin le contenu. Le bloc "body" ressemblera à ceci
{% block body %}
<h1>{{ article.titre }}</h1>
<p>{{ article.createdAt|date }}</p>
<div>{{ article.contenu|raw }}</div>
{% endblock %}
Vous remarquerez l'utilisation de "|date" et "|raw" pour la date et le contenu.
Ce sont des filtres twig, qui permettent de modifier la façon dont les contenus seront affichés.
En effet, la date est envoyée sous forme d'un objet date et doit être affichée sous forme de texte. Le filtre "date" permet de convertir l'objet en chaîne de caractères.
Le filtre "raw" quant à lui, permet d'afficher du code html en l'interprétant. En effet, le contenu sera en html et il devra être interprété pour son affichage.
Les catégories
Le cas particulier des catégories est lié à la structure relationnelle de notre base de données qui permet d'avoir un article dans plusieurs catégories.
Grâce à Doctrine, nous avons accès, depuis notre variable "article", à la liste des catégories dont fait partie notre article.
Nous allons donc effectuer une boucle afin d'afficher ces catégories. Elles sont accessibles depuis la propriété "categories", nous accèderons donc à "article.categories" comme ci-dessous
{% for categorie in article.categories %}
{{ categorie.nom }}
{% endfor %}
Notre vue finalisée ressemblera donc à ceci
{% extends 'base.html.twig' %}
{% block title %}{{ article.titre }}{% endblock %}
{% block body %}
<h1>{{ article.titre }}</h1>
<p>{{ article.createdAt|date }}</p>
<div>{{ article.contenu|raw }}</div>
<p>Catégories :
{% for categorie in article.categories %}
{{ categorie.nom }}
{% endfor %}
</p>
{% endblock %}
Et voilà, nous verrons prochainement comment relier toutes ces pages.
Obtenir de l'aide
Pour obtenir de l'aide, vous pouvez accéder au serveur Discord pour une entraide par chat