Chill Documentation
latest
  • Installation & Usage
  • Development
    • Instructions to create a new bundle
    • CRUD (Create - Update - Delete) for one entity
    • Helpers for building a REST API
    • Routing
    • Menus
    • Forms
    • Access control model
    • Messages to users
    • Pagination
      • A simple example
        • Understanding the magic
      • PaginatorFactory, Paginator and Page
        • PaginatorFactory
        • Working with Paginator and Page
      • Customizing the rendering of twig’s chill_pagination
    • Localisation
    • Logging
    • Database migrations
    • Searching
    • Timelines
    • Exports
    • Embeddable comments
    • Run tests
    • Useful snippets
    • Developer manual
    • Assets
    • Cron Jobs
    • Layout and UI
    • Help, I am lost !
  • Bundles
Chill Documentation
  • »
  • Development »
  • Pagination
  • Edit on GitLab

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.

../_images/pagination-sequence.png

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.

Next Previous

© Copyright 2014-2016, Champs-Libres, published under the terms of the GNU Free Documentation License, Version 1.3 Revision 331443ae.

Built with Sphinx using a theme provided by Read the Docs.
Read the Docs v: latest
Versions
latest
stable
Downloads
On Read the Docs
Project Home
Builds