Pagination¶
The Bundle Chill\MainBundle
provides a Pagination api which allow you to easily divide results list on different pages.
A simple example¶
In the controller, get the Chill\Main\Pagination\PaginatorFactory
from the Container and use this PaginatorFactory
to create a Paginator
instance.
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MyBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class example extends Controller
{
public function yourAction()
{
$em = $this->getDoctrine()->getManager();
// first, get the number of total item are available
$total = $em
->createQuery('SELECT COUNT (item.id) FROM ChillMyBundle:Item item')
->getSingleScalarResult();
// get the PaginatorFactory
$paginatorFactory = $this->get('chill_main.paginator_factory');
// create a pagination instance. This instance is only valid for
// the current route and parameters
$paginator = $paginatorFactory->create($total);
// launch your query on item. Limit the query to the results
// for the current page using the paginator
$items = $em->createQuery('SELECT item FROM ChillMyBundle:Item item WHERE <your clause>')
// use the paginator to get the first item number
->setFirstResult($paginator->getCurrentPage()->getFirstItemNumber())
// use the paginator to get the number of items to display
->setMaxResults($paginator->getItemsPerPage());
return $this->render(
'ChillMyBundle:Item:list.html.twig',
[
'items' => $items,
'paginator' => $paginator,
]
);
}
}
Then, render the pagination using the dedicated twig function.
{% extends "@ChillPerson/Person/layout.html.twig" %}
{% block title 'Item list'|trans %}
{% block content %}
<table>
{# ... your items here... #}
</table>
{% if items|length < paginator.getTotalItems %}
{{ chill_pagination(paginator) }}
{% endif %}
The function chill_pagination
will, by default, render a link to the 10 previous page (if they exists) and the 10 next pages (if they exists). Assuming that we are on page 5, the function will render a list to
Previous 1 2 3 4 **5** 6 7 8 9 10 11 12 13 14 Next
Understanding the magic¶
Where does the $paginator
get the page number ?¶
Internally, the $paginator
object has a link to the Request
object, and it reads the page
parameter which contains the current page number. If this parameter is not present, the $paginator
assumes that we are on page 1.

The $paginator
get the current page from the request.
Where does the $paginator
get the number of items per page ?¶
As above, the $paginator
can get the number of items per page from the Request
. If none is provided, this is given by the configuration which is, by default, 50 items per page.
PaginatorFactory
, Paginator
and Page
¶
PaginatorFactory
¶
The PaginatorFactory
may create more than one Paginator
in a single action. Those Paginator
instance may redirect to different routes and/or routes parameters.
// create a paginator for the route 'my_route' with some parameters (arg1 and arg2)
$paginatorMyRoute = $paginatorFactory->create($total, 'my_route', array('arg1' => 'foo', 'arg2' => $bar);
Those parameters will override the current parameters.
The PaginatorFactory
has also some useful shortcuts :
// get current page number
$paginatorFactory->getCurrentPageNumber( )
// get the number of items per page **for the current request**
$paginatorFactory->getCurrentItemsPerPage( )
// get the number of the first item **for the current page**
$paginatorFactory->getCurrentPageFirstItemNumber( )
Working with Paginator
and Page
¶
The paginator has some function to give the number of pages are required to displayed all the results, and give some information about the number of items per page :
// how many page count this paginator ?
$paginator->countPages(); // return 20 in our example
// we may get the number of items per page
$paginator->getItemsPerPage(); // return 20 in our example
A Paginator
instance create instance of Page
, each Page
, which is responsible for generating the URL to the page number it represents. Here are some possibilities using Page
and Paginator
:
// get the current page
$page = $paginator->getCurrentPage();
// on which page are we ?
$page->getNumber(); // return 5 in this example (we are on page 5)
// generate the url for page 5
$page->generateUrl(); // return '/<your route here>?page=5
// what is the first item number on this page ?
$page->getFistItemNumber(); // return 101 in our example (20 items per page)
// what is the last item number on this page ?
$page->getLastItemNumber(); // return 120 in our example
// we can access directly the next and current page
if ($paginator->hasNextPage()) {
$next = $paginator->getNextPage();
}
if ($paginator->hasPreviousPage()) {
$previous = $paginator->getPreviousPage();
}
// we can access directly to a given page number
if ($paginator->hasPage(10)) {
$page10 = $paginator->getPage(10);
}
// we can iterate over our pages through a generator
foreach ($paginator->getPagesGenerator() as $page) {
$page->getNumber();
}
// check that a page object is the current page
$paginator->isCurrentPage($page); // return false
Warning
When calling a page which does not exists, the Paginator
will throw a RuntimeException. Example :
// our last page is 10
$paginator->getPage(99); // out of range => throw `RuntimeException`
// our current page is 1 (the first page)
$paginator->getPreviousPage; // does not exists (the fist page is always 1) => throw `RuntimeException`
Note
When you create a Paginator
for the current route and route parameters, the Page
instances will keep the same parameters and routes :
// assuming our route is 'my_route', for the pattern '/my/{foo}/route',
// and the current route is '/my/value/route?arg2=bar'
// create a paginator for the current route and route parameters :
$paginator = $paginatorFactory->create($total);
// get the next page
if ($paginator->hasNext()) {
$next = $paginator->getNextPage();
// get the route to the page
$page->generateUrl(); // will print 'my/value/route?arg2=bar&page=2'
}
Having a look to the full classes documentation may provide some useful information.
Customizing the rendering of twig’s chill_pagination
¶
You can provide your own layout for rendering the pagination: provides your twig template as a second argument :
{{ chill_pagination(paginator, 'MyBundle:Pagination:MyTemplate.html.twig') }}
The template will receive the $paginator
as paginator
variable. Let’s have a look at the current template.