.. Copyright (C) 2016 Champs Libres Cooperative SCRLFS Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". .. _pagination-ref: Pagination ########## The Bundle :code:`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 :code:`Chill\Main\Pagination\PaginatorFactory` from the `Container` and use this :code:`PaginatorFactory` to create a :code:`Paginator` instance. .. literalinclude:: pagination/example.php :language: php Then, render the pagination using the dedicated twig function. .. code-block:: html+twig {% extends "@ChillPerson/Person/layout.html.twig" %} {% block title 'Item list'|trans %} {% block content %} {# ... your items here... #}
{% if items|length < paginator.getTotalItems %} {{ chill_pagination(paginator) }} {% endif %} The function :code:`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 :code:`$paginator` get the page number ? ------------------------------------------------------- Internally, the :code:`$paginator` object has a link to the :code:`Request` object, and it reads the :code:`page` parameter which contains the current page number. If this parameter is not present, the :code:`$paginator` assumes that we are on page 1. .. figure:: /_static/puml/pagination-sequence.png The :code:`$paginator` get the current page from the request. Where does the :code:`$paginator` get the number of items per page ? -------------------------------------------------------------------- As above, the :code:`$paginator` can get the number of items per page from the :code:`Request`. If none is provided, this is given by the configuration which is, by default, 50 items per page. :code:`PaginatorFactory`, :code:`Paginator` and :code:`Page` ************************************************************ :code:`PaginatorFactory` ======================== The :code:`PaginatorFactory` may create more than one :code:`Paginator` in a single action. Those :code:`Paginator` instance may redirect to different routes and/or routes parameters. .. code-block:: php // 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 :code:`PaginatorFactory` has also some useful shortcuts : .. code-block:: php // 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 :code:`Paginator` and :code:`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 : .. code-block:: php // 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 :code:`Paginator` instance create instance of :code:`Page`, each :code:`Page`, which is responsible for generating the URL to the page number it represents. Here are some possibilities using :code:`Page` and :code:`Paginator` : .. code-block:: php // 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 '/?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 :code:`Paginator` will throw a `RuntimeException`. Example : .. code-block:: php // 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 :code:`Paginator` for the current route and route parameters, the :code:`Page` instances will keep the same parameters and routes : .. code-block:: php // 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 :code:`chill_pagination` ************************************************************ You can provide your own layout for rendering the pagination: provides your twig template as a second argument : .. code-block:: html+jinja {{ chill_pagination(paginator, 'MyBundle:Pagination:MyTemplate.html.twig') }} The template will receive the :code:`$paginator` as :code:`paginator` variable. Let's have a look `at the current template `_.