5.7 KiB
Pagination
The Bundle Chill\MainBundle provides a Pagination api which allow you to easily divide result 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.
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 a function to give the number of pages that are required to display 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
$page10 = $paginator->getPage(10);``
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
When calling a page which does not exist, the [Paginatorwill throw aRuntimeException`. 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`
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 at 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 .