Symfony 4 - Créer un blog pas à pas - Mettre en place la pagination

11 août 2019 - : MVC Tutoriel Symfony - : 9 commentaires - Tutoriel Framework MVC Views Symfony Pagination

Visualisez les fichiers de cette série sur GitHub

Dernière modification le 11 mars 2020

Dans l'article précédent, nous avons affiché les articles sur la page actualités sans nous soucier de la pagination.

Cette pagination pourraît s'effectuer manuellement en calculant le nombre de pages, l'offset et en passant en paramètre le numéro de la page actuelle.

Avec Symfony, il existe une solution plus simple sous la forme d'un bundle publié par KNP Labs et appelé KNP Paginator Bundle.

Sa mise en oeuvre est simple et permet de mettre en place une pagination gérée depuis le contrôleur et affichée dans la vue.

Nous allons prendre pour exemple la page contenant la liste des articles créée dans l'article précédent.

Nous allons créer des pages de 6 articles.

Installation de KNP Paginator

Afin d'intégrer KNP Paginator à notre projet, nous allons faire appel à composer au moyen de la commande suivante

composer require knplabs/knp-paginator-bundle

Et c'est tout, le bundle est installé.

ATTENTION : depuis la sortie de Symfony 5, il est possible que l'installation seule ne suffise plus.

Si vous avez une erreur " There are no registered paths for namespace "KnpPaginator" ", insérez les lignes ci-dessous dans " config\packages\twig.yaml "

paths:
    '%kernel.project_dir%/vendor/knplabs/knp-paginator-bundle/templates': KnpPaginator

Activation de la pagination dans le contrôleur

Pour activer la pagination dans le contrôleur, il est nécessaire de comprendre le concept de KNP Paginator.

Il nécessite dans un premier temps de récupérer toutes les données devant être paginées. Dans notre exemple, il s'agit de tous les articles.

KNP Paginator se chargera de "filtrer" cette liste et de conserver uniquement les données correspondant à la page courante.

Nous utiliserons la méthode "paginate" qui se chargera de tout ça.

Cette méthode prend 3 paramètres comme dans l'exemple ci-dessous.

$articles = $paginator->paginate(
    $donnees, // Requête contenant les données à paginer (ici nos articles)
    $request->query->getInt('page', 1), // Numéro de la page en cours, passé dans l'URL, 1 si aucune page
    6 // Nombre de résultats par page
);

Nous devrons donc modifier notre contrôleur "ArticlesController" comme dans cet exemple

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use App\Entity\Articles;
use Symfony\Component\HttpFoundation\Request; // Nous avons besoin d'accéder à la requête pour obtenir le numéro de page
use Knp\Component\Pager\PaginatorInterface; // Nous appelons le bundle KNP Paginator

class ArticlesController extends AbstractController
{
    /**
     * @Route("/articles", name="articles")
     */
    public function index(Request $request, PaginatorInterface $paginator) // Nous ajoutons les paramètres requis
    {
        // Méthode findBy qui permet de récupérer les données avec des critères de filtre et de tri
        $donnees = $this->getDoctrine()->getRepository(Articles::class)->findBy([],['created_at' => 'desc']);

        $articles = $paginator->paginate(
            $donnees, // Requête contenant les données à paginer (ici nos articles)
            $request->query->getInt('page', 1), // Numéro de la page en cours, passé dans l'URL, 1 si aucune page
            6 // Nombre de résultats par page
        );
        
        return $this->render('articles/index.html.twig', [
            'articles' => $articles,
        ]);
    }
}

Affichage de la pagination dans la vue

Une fois les données envoyées à la vue, nous pouvons y afficher le sélecteur de pages au moyen de la méthode "knp_pagination_render" comme dans le code ci-dessous, dans le fichier "index.html.twig" du dossier "articles"

{% extends 'base.html.twig' %}

{% block title %}Liste des articles{% endblock %}

{% block body %}
    <h1>Liste des articles</h1>
    {% for article in articles %}
        <h2>{{ article.titre }}</h2>
        <div>{{ article.contenu }}</div>
    {% endfor %}
    {{ knp_pagination_render(articles) }}
{% endblock %}

Et voilà comment ajouter une pagination.

Obtenir de l'aide

Pour obtenir de l'aide, vous pouvez accéder au serveur Discord pour une entraide par chat

Visualisez les fichiers de cette série sur GitHub

Partager

Partager sur Facebook Partager sur Twitter Partager sur LinkedIn

Commentaires

Ecrire un commentaire

faf a écrit le 9 mai 2020 à 01:32

bonjour je suis votre tuto mais je voudrais savoir si il maanque pas des videos car votre ecran presente plusieurs lignes de codes que je ne n ai pas .votre base de donneés en pleine portant je n 'ai pas ces tutos ? sinon vos explication sont tres claires merci beaucoup

Répondre

MarcD a écrit le 29 avril 2020 à 16:46

Superbe article, mise en place très facile grâce à vos conseils.

Un grand MERCI

Répondre

znimed a écrit le 4 avril 2020 à 18:27

Bonjour, 

Moi j'ai essayé de suivre le tuto et j'ai cette erreur

Controller "PN\PlatformBundle\Controller\PlatformController::categoryAction()" requires that you provide a value for the "$paginator" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one.

 

Répondre

Nouvelle-Techno.fr a répondu le 7 avril 2020 à 12:05

Bonjour,

Il faudrait une capture d'écran de l'erreur. Une discussion sur Discord (https://discord.gg/azQ9sbD) serait plus facile.

Merci

Répondre

Rahinatou a écrit le 21 janvier 2020 à 10:13

Bonjour

j'ai essayé votre methode mais j'ai l' erreur que vois-ci:

     

{% for result in resultOp %}
     <tr> 
           <td> {{ result.numeroRecu }} </td>
           <td> {{ result.dateOperation|date('d/m/Y') }} </td>
           <td> {{ result.idTypeOperation.libelleTypeOperation }} </td>
           <td> {{ result.idUser.nomUser }} {{ result.idUser.prenomUser }}</td>
    </tr>

 {% endfor %}
 {{ knp_pagination_render(resultOp) }}

voici l'erreur qu'il m'affiche:

          There are no registered paths for namespace "KnpPaginator".

 

 

Merci d'avance

Répondre

Nouvelle-Techno.fr a répondu le 21 janvier 2020 à 10:27

Bonjour,

Essaie d'ajouter ceci dans config\packages\twig.yaml

paths:
    '%kernel.project_dir%/vendor/knplabs/knp-paginator-bundle/templates': KnpPaginator

 

Répondre

numa a écrit le 18 novembre 2019 à 14:19

Merci merci. très bon article . Facile à mettre en place

Répondre

Nouvelle-Techno.fr a écrit le 18 septembre 2019 à 06:04

Bonjour,

Il y a une erreur sur cette ligne

// Votre ligne
$request->query->getInt('page, 1')

// Ce qu'il faut écrire 
$request->query->getInt('page', 1)

 

Répondre

Exi a écrit le 18 septembre 2019 à 01:32

Bonjour à vous,

J'ai testé votre méthode pour la pagination mais j'ai un problème ici :

<pre><code>

$articles = $paginator->paginate(
    $donnees, // Les données à paginer
    $request->query->getInt('page, 1'), // Numéro de la page en cours passée dans l'URL, 1 si aucune page
    6 // Nombre de résultats par page
);</code></pre>

Cela m'affiche l'erreur : 

Invalid item per page number. Limit: 6 and Page: 0, must be positive non-zero integers

En vous remerciant d'avance ! 

Répondre

Ecrire un commentaire