SUPERCAT.DEV

Benvenut* sul mio blog

SYMFONY

Gestione paginazione

20-08-2022

Paginazione con KnpPaginatorBundle

Ho scelto questo bundle per la paginazione
Puoi trovare il codice su Github
Link Github KnpPaginatorBundle

Per installarlo:

composer require knplabs/knp-paginator-bundle

Aggiungo il file di configurazione "config/packages/knp_paginator.yaml"

knp_paginator:
    page_range: 5                       # number of links shown in the pagination menu (e.g: you have 10 pages, a page_range of 3, on the 5th page you'll see links to page 4, 5, 6)
    default_options:
        page_name: page                 # "page" nome del parametro di route - es. ?page=1
        sort_field_name: sort           # sort field query parameter name
        sort_direction_name: direction  # sort direction query parameter name
        distinct: true                  # ensure distinct results, useful when ORM queries are using GROUP BY statements
        filter_field_name: filterField  # filter field query parameter name
        filter_value_name: filterValue  # filter value query parameter name
    template:
        pagination: '@KnpPaginator/Pagination/sliding.html.twig'     # sliding pagination controls template
        sortable: '@KnpPaginator/Pagination/sortable_link.html.twig' # sort link template
        filtration: '@KnpPaginator/Pagination/filtration.html.twig'  # filters template

Oppure un più semplice

knp_paginator:
    default_options:
        page_out_of_range: fix # Se chiedo una pagina non esistente mi restituisce l'ultima
    template:
        pagination: '@KnpPaginator/Pagination/bootstrap_v5_pagination.html.twig'

Nell'Entity Post metto la costante così so dove trovarla, altrimenti potrei nei parametri

class Post
{
    public const NUM_ITEMS_PER_PAGE = 10;
    ...

Nel controller in cui voglio fare la paginazione devo iniettare PaginatorInterface

use Knp\Component\Pager\PaginatorInterface;

...

#[Route('/', name: 'app_home', methods: ['GET'])]
    public function index(Request $request, PaginatorInterface $paginator): Response
    {
        $query = $this->postRepository->getAllPublishedOrderedQuery();

        $page = $request->query->getInt('page', 1);
        $pagination = $paginator->paginate(
            $query,
            $page,
            Post::NUM_ITEMS_PER_PAGE
        );

        return $this->render('posts/index.html.twig', ['pagination' => $pagination]);
    }

Il metodo "$this->postRepository->getAllPublishedOrderedQuery()" deve restituirmi non un array ma una query
Per cui nel PostRepository tolgo il "->getResult()" finale

...
public function getAllPublishedOrderedQuery(): Query
    {
        return $this->createQueryBuilder('p')
            ->andWhere('p.publishedAt IS NOT NULL')
            ->orderBy('p.publishedAt', 'DESC')
            ->getQuery()
        ;
    }
...

Ora nel file twig posso cambiare il loop for con la variabile passata e aggiungere con il div finale i link di paginazione

{% for post in pagination %}
    ...
{% endfor %}

<div>
    {{ knp_pagination_render(pagination) }}
</div>

Se volessi il numero totale di post

{{ pagination.getTotalItemCount }}