Dès que tu dépasses dix articles, un listing simple ne suffit plus. Il faut un vrai parcours de navigation.
On met en place une recherche simple mais utile, et une pagination propre.
Objectif d’apprentissage
Permettre aux lecteurs de trouver rapidement un article via recherche et filtres, avec une pagination claire et SEO-friendly.
Ce que tu vas pratiquer aujourd’hui
- Ajouter un champ de recherche GET.
- Filtrer par catégorie ou tag.
- Paginer proprement côté repository.
- Conserver des URLs propres et partageables.
1. Créer la requête paginée côté repository
Évite de charger toute la table en mémoire. La pagination doit être gérée dans la requête SQL.
Garde une méthode dédiée au listing filtré.
public function findPublishedPaginated(?string $search, int $limit, int $offset): array
{
$qb = $this->createQueryBuilder('post')
->andWhere('post.status = :status')
->setParameter('status', BlogPost::STATUS_PUBLISHED)
->orderBy('post.publishedAt', 'DESC');
if ($search) {
$qb->andWhere('post.title LIKE :q OR post.excerpt LIKE :q')
->setParameter('q', '%' . $search . '%');
}
return $qb->setMaxResults($limit)->setFirstResult($offset)->getQuery()->getResult();
}
2. Lire les filtres dans le controller
On lit la query string en GET pour garder des URLs indexables et partageables.
La logique reste simple: parser, compter, récupérer.
$q = trim((string) $request->query->get('q', ''));
$page = max(1, $request->query->getInt('page', 1));
$perPage = 9;
$offset = ($page - 1) * $perPage;
$posts = $blogPostRepository->findPublishedPaginated($q !== '' ? $q : null, $perPage, $offset);
3. Afficher la pagination en Twig
Génère les liens de pagination avec les filtres actifs pour ne pas perdre le contexte utilisateur.
Évite les liens cassés ou les pages vides.
{% for i in 1..pagination.totalPages %}
<a href="{{ path('app_blog_index', queryFilters|merge({page: i})) }}"
class="{{ i == pagination.currentPage ? 'is-active' : '' }}">
{{ i }}
</a>
{% endfor %}
Checklist de fin de session
- Recherche GET fonctionnelle.
- Pagination côté SQL en place.
- Liens de pages corrects.
- Filtres conservés lors de la navigation.
Erreurs fréquentes à éviter
- Sauter la vérification finale parce que “ça marche chez moi”.
- Mélanger trop de logique dans le
controllerau lieu de garder un flux clair. - Oublier la cohérence entre la donnée, le
templateTwig et le comportement en production.
Pourquoi cette étape compte en conditions réelles
Dans un vrai projet client, chaque étape technique doit rester compréhensible par l’équipe, duplicable sur un autre environnement et fiable dans le temps. Ici, l’objectif est de transformer la théorie en un flux de travail concret, avec des décisions simples que tu peux défendre en revue de code.
Si tu appliques sérieusement les points du jour (ajouter un champ de recherche get.), tu réduis la dette technique dès le départ et tu facilites la suite: SEO, publication, maintenance et déploiement. C’est exactement la différence entre un blog “démo” et un blog exploitable en production.
Mini plan de révision
- Reprends ce point et explique-le à voix haute comme si tu faisais un
code review: Ajouter un champ de recherche GET. - Reprends ce point et explique-le à voix haute comme si tu faisais un
code review: Filtrer par catégorie ou tag. - Reprends ce point et explique-le à voix haute comme si tu faisais un
code review: Paginer proprement côté repository.
Exercice rapide
Ajoute un filtre “temps de lecture max” pour les lecteurs qui veulent des formats courts.
Et demain ?
Demain, on traite le SEO on-page: metas dynamiques, canonical et JSON-LD minimal.