Friendly Symfony paginator to paginate everything, (*1)
, (*2)
Generally this bundle is based on Knp Pager component. This
component introduces a different way of pagination handling. You can read more about the
internal logic on the given documentation link., (*3)
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, (*4)
Latest updates
For details regarding changes please read about the releases., (*5)
Requirements:
Knp Pager component >=4.4.
KnpPaginatorBundle's master is compatible with Symfony >=6.4 versions.
Twig >=3.0 version is required if you use the Twig templating engine.
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., (*6)
If you don't use flex (you should), you need to manually enable bundle:, (*7)
// app/AppKernel.php
public function registerBundles()
{
return [
// ...
new Knp\Bundle\PaginatorBundle\KnpPaginatorBundle(),
// ...
];
}
, (*8)
Configuration example
You can configure default query parameter names and templates, and a few other options:, (*9)
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
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', // 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:
- `array`
- `Doctrine\DBAL\Query\QueryBuilder`
- `Doctrine\ORM\Query`
- `Doctrine\ORM\QueryBuilder`
- `Doctrine\ODM\MongoDB\Query\Query`
- `Doctrine\ODM\MongoDB\Query\Builder`
- `Doctrine\ODM\PHPCR\Query\Query`
- `Doctrine\ODM\PHPCR\Query\Builder\QueryBuilder`
- `Doctrine\Common\Collection\ArrayCollection` - any Doctrine relation collection including
- `ModelCriteria` - Propel ORM query
- array with `Solarium_Client` and `Solarium_Query_Select` as elements
```php
// 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 ``:
```twig
{# rel links for pagination #}
{{ knp_pagination_rel_links(pagination) }}
```
#### In ``:
```twig
{# total items count #}
{{ pagination.getTotalItemCount }}
{# sorting of properties based on query components #}
```
### Translation in view
For translating the following text:
* `%foo% name` with translation key `table_header_name`. The translation is in the domain `messages`.
* `{0} No author|{1} Author|[2,Inf] Authors` with translation key `table_header_author`. The translation is in the domain `messages`.
translationCount and translationParameters can be combined.
```twig
{# sorting of properties based on query components #}
```
### Adding translation files
You can also override translations by creating a translation file in the following name format: `domain.locale.format`.
So, to create a translation file for this bundle you need to create for instance `KnpPaginatorBundle.tr.yaml` file under `project_root/translations/`
and add your translations there:
```yaml
label_previous: "Önceki"
label_next: "Sonraki"
filter_searchword: "Arama kelimesi"
```
If you set default translation for configuration accordingly:
```yaml
framework:
default_locale: tr
```
Symfony will pick it automatically.
### Dependency Injection
You can automatically inject a paginator service into another service by using the `knp_paginator.injectable` DIC tag.
The tag takes one optional argument `paginator`, which is the ID of the paginator service that should be injected.
It defaults to `knp_paginator`.
The class that receives the KnpPaginator service must implement `Knp\Bundle\PaginatorBundle\Definition\PaginatorAwareInterface`.
If you're too lazy you can also just extend the `Knp\Bundle\PaginatorBundle\Definition\PaginatorAware` base class.
> **⚠ Warning** using `PaginatorAwareInterface` is discouraged, and could be removed in a future version. You should not rely on setter
> injection, but only on proper constructor injection. Using Symfony built-in autowiring mechanism is the suggested way to go.
#### Lazy service
The `knp_paginator` service will be created lazily if the package `symfony/proxy-manager-bridge` is installed.
For more information about lazy services, consult the [Symfony documentation on dependency injection](https://symfony.com/doc/current/service_container/lazy_services.html).
###### XML configuration example
```xml
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="my_bundle.paginator_aware.class">MyBundle\Repository\PaginatorAwareRepository</parameter>
</parameters>
<services>
<service id="my_bundle.paginator_aware" class="my_bundle.paginator_aware.class">
<tag name="knp_paginator.injectable" paginator="knp_paginator" />
</service>
</services>
</container>
Troubleshooting
Make sure the translator is activated in your Symfony config:
If your locale is not available, create your own translation file in
translations/KnpPaginatorBundle.en.yml (substitute "en" for your own language code if needed).
Then add these lines:
label_next: Next
label_previous: Previous
Note that <rel> links are only meaningful when using pagination, they are not relevant to sorting or filtering.