KnpPaginatorBundle
SEO friendly Symfony paginator to sort and paginate
Install / Use
/learn @KnpLabs/KnpPaginatorBundleREADME
Intro to KnpPaginatorBundle
Friendly Symfony paginator to paginate everything
Generally this bundle is based on [Knp Pager component][knp_component_pager]. This component introduces a different way of pagination handling. You can read more about the internal logic on the given documentation link.
Note: Keep knp-components in sync with this bundle. If you want to use older version of KnpPaginatorBundle - use v3.0 or v4.X tags in the repository which is suitable to paginate ODM MongoDB and ORM 2.0 queries
Latest updates
For details regarding changes please read about the releases.
Requirements:
- Knp Pager component
>=4.4. - KnpPaginatorBundle's master is compatible with Symfony
>=6.4versions. - Twig
>=3.0version is required if you use the Twig templating engine. - If you want to use the provided templates, you need the Translation component too.
Features:
- Does not require initializing specific adapters.
- Can be customized in any way needed, etc.: pagination view, event subscribers.
- Possibility to add custom filtering, sorting functionality depending on request parameters.
- Separation of concerns, paginator is responsible for generating the pagination view only, pagination view - for representation purposes.
Note: using multiple paginators requires setting the alias in order to keep non conflicting parameters.
More detailed documentation:
- Creating [custom pagination subscribers][doc_custom_pagination_subscriber]
- [Customizing view][doc_templates] templates and arguments
Installation and configuration:
Pretty simple with Composer, run
composer require knplabs/knp-paginator-bundle
Add PaginatorBundle to your application kernel
If you don't use flex (you should), you need to manually enable bundle:
// app/AppKernel.php
public function registerBundles()
{
return [
// ...
new Knp\Bundle\PaginatorBundle\KnpPaginatorBundle(),
// ...
];
}
<a name="configuration"></a>
Configuration example
You can configure default query parameter names and templates, and a few other options:
YAML:
knp_paginator:
convert_exception: false # throw a 404 exception when an invalid page is requested
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)
remove_first_page_param: false # remove the page query parameter from the first page link
default_options:
page_name: page # page query parameter name
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
page_out_of_range: ignore # ignore, fix, or throwException when the page is out of range
default_limit: 10 # default number of items per page
template:
pagination: '@KnpPaginator/Pagination/sliding.html.twig' # sliding pagination controls template
rel_links: '@KnpPaginator/Pagination/rel_links.html.twig' # <link rel=...> tags template
sortable: '@KnpPaginator/Pagination/sortable_link.html.twig' # sort link template
filtration: '@KnpPaginator/Pagination/filtration.html.twig' # filters template
PHP:
// config/packages/paginator.php
<?php declare(strict_types=1);
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $configurator): void
{
$configurator->extension('knp_paginator', [
'convert_exception' => false, // throw a 404 exception when an invalid page is requested
'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
'remove_first_page_param' => false, // remove the page query parameter from the first page link
'default_options' => [
'page_name' => 'page', // page query parameter name
'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
'page_out_of_range' => 'ignore', // ignore, fix, or throwException when the page is out of range
'default_limit' => 10 // default number of items per page
],
'template' => [
'pagination' => '@KnpPaginator/Pagination/sliding.html.twig', // sliding pagination controls template
'rel_links' => '@KnpPaginator/Pagination/rel_links.html.twig', // <link rel=...> tags template
'sortable' => '@KnpPaginator/Pagination/sortable_link.html.twig', // sort link template
'filtration' => '@KnpPaginator/Pagination/filtration.html.twig' // filters template
]
]);
};
Additional pagination templates
That could be used out of the box in knp_paginator.template.pagination key:
@KnpPaginator/Pagination/sliding.html.twig(by default)@KnpPaginator/Pagination/bootstrap_v5_pagination.html.twig@KnpPaginator/Pagination/twitter_bootstrap_v4_pagination.html.twig@KnpPaginator/Pagination/twitter_bootstrap_v3_pagination.html.twig@KnpPaginator/Pagination/twitter_bootstrap_pagination.html.twig@KnpPaginator/Pagination/foundation_v6_pagination.html.twig@KnpPaginator/Pagination/foundation_v5_pagination.html.twig@KnpPaginator/Pagination/bulma_pagination.html.twig@KnpPaginator/Pagination/semantic_ui_pagination.html.twig@KnpPaginator/Pagination/materialize_pagination.html.twig@KnpPaginator/Pagination/tailwindcss_pagination.html.twig@KnpPaginator/Pagination/uikit_v3_pagination.html.twig
Sample rel link tag template
That could be used out of the box in knp_paginator.template.rel_links key:
@KnpPaginator/Pagination/rel_links.html.twig(by default)
Additional sortable templates
That could be used out of the box in knp_paginator.template.sortable key:
@KnpPaginator/Pagination/sortable_link.html.twig(by default)@KnpPaginator/Pagination/bootstrap_v5_bi_sortable_link.html.twig@KnpPaginator/Pagination/bootstrap_v5_fa_sortable_link.html.twig@KnpPaginator/Pagination/bootstrap_v5_md_sortable_link.html.twig@KnpPaginator/Pagination/twitter_bootstrap_v3_sortable_link.html.twig@KnpPaginator/Pagination/twitter_bootstrap_v4_font_awesome_sortable_link.html.twig@KnpPaginator/Pagination/twitter_bootstrap_v4_material_design_icons_sortable_link.html.twig@KnpPaginator/Pagination/semantic_ui_sortable_link.html.twig@KnpPaginator/Pagination/uikit_v3_sortable.html.twig
Additional filtration templates
That could be used out of the box in knp_paginator.template.filtration key:
@KnpPaginator/Pagination/filtration.html.twig(by default)@KnpPaginator/Pagination/bootstrap_v5_filtration.html.twig@KnpPaginator/Pagination/twitter_bootstrap_v4_filtration.html.twig
Usage examples:
Controller
Currently paginator can paginate:
arrayDoctrine\DBAL\Query\QueryBuilderDoctrine\ORM\QueryDoctrine\ORM\QueryBuilderDoctrine\ODM\MongoDB\Query\QueryDoctrine\ODM\MongoDB\Query\BuilderDoctrine\ODM\PHPCR\Query\QueryDoctrine\ODM\PHPCR\Query\Builder\QueryBuilderDoctrine\Common\Collection\ArrayCollection- any Doctrine relation collection includingModelCriteria- Propel ORM query- array with
Solarium_ClientandSolarium_Query_Selectas elements
// App\Controller\ArticleController.php
public function listAction(EntityManagerInterface $em, PaginatorInterface $paginator, Request $request)
{
$dql = "SELECT a FROM AcmeMainBundle:Article a";
$query = $em->createQuery($dql);
$pagination = $paginator->paginate(
$query, /* query NOT result */
$request->query->getInt('page', 1), /* page number */
10 /* limit per page */
);
// parameters to template
return $this->render('article/list.html.twig', ['pagination' => $pagination]);
}
View
In <head>:
{# rel links for pagination #}
{{ knp_pagination_rel_links(pagination) }}
In <body>:
{# total items count #}
<div class="count">
{{ pagination.getTotalItemCount }}
</div>
<table>
<tr>
{# sorting of properties based on query components #}
<th>{{ knp_pagination_sortable(pagination, 'Id', 'a.id') }}</th>
<th{% if pagination.isSorted('a.title') %} class="sorted"{% endif %}>
{{ knp_pagination_sortable(pagination, 'Title', 'a.title') }}
</th>
<th{% if pagination.isSorted(['a.date', 'a.time']) %} class="sorted"{% endif %}>
{{ knp_pagination_sortable(pagination, 'Release', ['a.date', 'a.time']) }}
</th>
</tr>
{# table body #}
{% for article in pagination %}
<tr {% if loop.index is odd %}class="color"{% endif %}>
<td>{{ article.id }}</td>
<td>{{ artic
Related Skills
bluebubbles
349.7kUse when you need to send or manage iMessages via BlueBubbles (recommended iMessage integration). Calls go through the generic message tool with channel="bluebubbles".
bear-notes
349.7kCreate, search, and manage Bear notes via grizzly CLI.
claude-seo
4.1kUniversal SEO skill for Claude Code. 19 sub-skills, 12 subagents, 3 extensions (DataForSEO, Firecrawl, Banana). Technical SEO, E-E-A-T, schema, GEO/AEO, backlinks, local SEO, maps intelligence, Google APIs, and PDF/Excel reporting.
claude-ads
1.6kComprehensive paid advertising audit & optimization skill for Claude Code. 186 checks across Google, Meta, YouTube, LinkedIn, TikTok & Microsoft Ads with weighted scoring, parallel agents, and industry templates.
