SEO friendly Symfony2 paginator to paginate everything
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
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.
- Creating custom pagination subscribers
- Extending pagination class (todo, may require some refactoring)
- Customizing view templates and arguments
Pretty simple with Composer, run:
composer require knplabs/knp-paginator-bundle
// app/AppKernel.php
public function registerBundles()
{
return array(
// ...
new Knp\Bundle\PaginatorBundle\KnpPaginatorBundle(),
// ...
);
}
You can configure default query parameter names and templates
knp_paginator:
page_range: 5 # default page range used in pagination control
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
template:
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
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 includingModelCriteria
- Propel ORM query- array with
Solarium_Client
andSolarium_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 }}
</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>{{ 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>{{ article.title }}</td>
<td>{{ article.date | date('Y-m-d') }}, {{ article.time | date('H:i:s') }}</td>
</tr>
{% endfor %}
</table>
{# display navigation #}
<div class="navigation">
{{ knp_pagination_render(pagination) }}
</div>
For translating the following text:
%foo% name
with translation keytable_header_name
. The translation is in the domainmessages
.{0} No author|{1} Author|[2,Inf] Authors
with translation keytable_header_author
. The translation is in the domainmessages
.
translationCount and translationParameters can be combined.
<table>
<tr>
{# sorting of properties based on query components #}
<th>{{ knp_pagination_sortable(pagination, 'Id'|trans({foo:'bar'},'messages'), 'a.id' )|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'), 'a.author' )|raw }}</th>
</tr>
<!-- Content of the table -->
</table>
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 version="1.0" ?>
<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>