KnpPaginatorBundle 0,0,0,1,0 Packagist

SEO friendly Symfony2 paginator to sort and paginate

3 years after

Intro to KnpPaginatorBundle

SEO friendly Symfony2 paginator to paginate everything

Build Status

Generally this bundle is based on Knp Pager component. This component introduces a different way for 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 v1.0 tag in the repository which is suitable to paginate ODM mongodb and ORM 2.0 queries

Latest updates

For notes about latest changes please read CHANGELOG, for required changes in your code please read UPGRADE chapter of documentation.


  • Knp pager component >=1.1
  • KnpPaginatorBundle's master compatible with symfony (>=2.0 versions).
  • Twig>=1.5 version is required if you use twig templating engine


  • 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. Also it gets quite complicated with a twig template, since hash arrays cannot use variables as keys.

More detailed documentation:

Installation and configuration:

Pretty simple with Composer, run:

composer require knplabs/knp-paginator-bundle

Add PaginatorBundle to your application kernel

// app/AppKernel.php
public function registerBundles()
    return array(
        // ...
        new Knp\Bundle\PaginatorBundle\KnpPaginatorBundle(),
        // ...

Configuration example

You can configure default query parameter names and templates

    page_range: 5                      # default page range used in pagination control
        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
        pagination: KnpPaginatorBundle:Pagination:sliding.html.twig     # sliding pagination controls template
        sortable: KnpPaginatorBundle:Pagination:sortable_link.html.twig # sort link template

There are a few additional pagination templates, that could be used out of the box in knp_paginator.template.pagination key:

  • KnpPaginatorBundle:Pagination:sliding.html.twig (by default)
  • KnpPaginatorBundle:Pagination:twitter_bootstrap_v3_pagination.html.twig
  • KnpPaginatorBundle:Pagination:twitter_bootstrap_pagination.html.twig
  • KnpPaginatorBundle:Pagination:foundation_v5_pagination.html.twig

Usage examples:


Currently paginator can paginate:

  • array
  • 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
// Acme\MainBundle\Controller\ArticleController.php

public function listAction(Request $request)
    $em    = $this->get('doctrine.orm.entity_manager');
    $dql   = "SELECT a FROM AcmeMainBundle:Article a";
    $query = $em->createQuery($dql);

    $paginator  = $this->get('knp_paginator');
    $pagination = $paginator->paginate(
        $query, /* query NOT result */
        $request->query->getInt('page', 1)/*page number*/,
        10/*limit per page*/

    // parameters to template
    return $this->render('AcmeMainBundle:Article:list.html.twig', array('pagination' => $pagination));


{# total items count #}
<div class="count">
    {{ pagination.getTotalItemCount }}
{# sorting of properties based on query components #}
    <th>{{ knp_pagination_sortable(pagination, 'Id', '') }}</th>
    <th{% if pagination.isSorted('a.Title') %} class="sorted"{% endif %}>{{ knp_pagination_sortable(pagination, 'Title', 'a.title') }}</th>
    <th>{{ knp_pagination_sortable(pagination, 'Release', ['', 'a.time']) }}</th>

{# table body #}
{% for article in pagination %}
<tr {% if loop.index is odd %}class="color"{% endif %}>
    <td>{{ }}</td>
    <td>{{ article.title }}</td>
    <td>{{ | date('Y-m-d') }}, {{ article.time | date('H:i:s') }}</td>
{% endfor %}
{# display navigation #}
<div class="navigation">
    {{ knp_pagination_render(pagination) }}

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.

{# sorting of properties based on query components #}
       <th>{{ knp_pagination_sortable(pagination, 'Id'|trans({foo:'bar'},'messages'), '' )|raw }}</th>
       <th{% if pagination.isSorted('a.Title') %} class="sorted"{% endif %}>{{ knp_pagination_sortable(pagination, 'Title', 'a.title')|raw }}</th>
       <th>{{ knp_pagination_sortable(pagination, 'Author'|trans({}, 'messages'), '' )|raw }}</th>

<!-- Content of the table -->


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.

XML configuration example
<?xml version="1.0" ?>

<container xmlns=""

        <parameter key="my_bundle.paginator_aware.class">MyBundle\Repository\PaginatorAwareRepository</parameter>

        <service id="my_bundle.paginator_aware" class="my_bundle.paginator_aware.class">
            <tag name="knp_paginator.injectable" paginator="knp_paginator" />

Related Repositories



Easy integration of twitters bootstrap into symfony2 ...



CrudGeneratorBundle ...



Forum Bundle for symfony 3 ...



Symfony 3 Forum Bundle ...



Easy integration of twitters bootstrap into symfony2 ...

Top Contributors

l3pp4rd stloyd ornicar pilot stof Herzult Inoryy docteurklein crackcomm mbontemps johnwards toberger sallaigy bocharsky-bw rafalwrzeszcz loostro thewholelifetolearn megawebmaster benji07 wysow jeremyb jonathaningram XWB MaksSlesarenko hason sroze VincentLoy ZhukV daFish imenem


package version
php >=5.3.3
symfony/framework-bundle ~2.7|~3.0
knplabs/knp-components ~1.2
twig/twig ~1.12|~2
dev symfony/expression-language ~2.7|~3.0
phpunit/phpunit ~4.8


-   v2.3.2 zip tar
-   v2.3.1 zip tar
-   v2.3 zip tar
-   v2.2 zip tar
-   v2.1 zip tar
-   v2.0 zip tar
-   v1.0 zip tar
-   2.5.3 zip tar
-   2.5.2 zip tar
-   2.5.1 zip tar
-   2.5.0 zip tar
-   2.4.2 zip tar
-   2.4.1 zip tar
-   2.4.0 zip tar
-   2.3.3 zip tar