Developed with love by KnpLabs Hire us for your project!
1332

KnpPaginatorBundle

by KnpLabs

SEO friendly Symfony paginator to sort and paginate

Intro to KnpPaginatorBundle

Friendly Symfony paginator to paginate everything

Build Status

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.

knpbundles.com

Note: Keep knp-components in sync with this bundle. If you want to use
older version of KnpPaginatorBundle - use v3.0 or v4.X tags in the repository which is
suitable to paginate ODM MongoDB and ORM 2.0 queries

Latest updates

For notes about latest changes please read CHANGELOG,
for required changes in your code please read UPGRADE
chapter of documentation.

Requirements:

  • Knp Pager component >=2.0.
  • KnpPaginatorBundle's master compatible with Symfony >=4.3 versions.
  • Twig >=2.0 version is required if you use twig templating engine.

Features:

  • 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.

More detailed documentation:

Installation and configuration:

Pretty simple with Composer, run

composer require knplabs/knp-paginator-bundle

Add PaginatorBundle to your application kernel

If you don't use flex (you should), you need to manually enable bundle:

// app/AppKernel.php
public function registerBundles()
{
    return [
        // ...
        new Knp\Bundle\PaginatorBundle\KnpPaginatorBundle(),
        // ...
    ];
}

Configuration example

You can configure default query parameter names and templates

knp_paginator:
    page_range: 5                       # number of links showed in the pagination menu (e.g: you have 10 pages, a page_range of 3, on the 5th page you'll see links to page 4, 5, 6)
    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
        filter_field_name: filterField  # filter field query parameter name
        filter_value_name: filterValue  # filter value query parameter name
    template:
        pagination: '@KnpPaginator/Pagination/sliding.html.twig'     # sliding pagination controls template
        sortable: '@KnpPaginator/Pagination/sortable_link.html.twig' # sort link template
        filtration: '@KnpPaginator/Pagination/filtration.html.twig'  # filters template

Additional pagination templates

That could be used out of the box in knp_paginator.template.pagination key:

  • @KnpPaginator/Pagination/sliding.html.twig (by default)
  • @KnpPaginator/Pagination/twitter_bootstrap_v4_pagination.html.twig
  • @KnpPaginator/Pagination/twitter_bootstrap_v3_pagination.html.twig
  • @KnpPaginator/Pagination/twitter_bootstrap_pagination.html.twig
  • @KnpPaginator/Pagination/foundation_v5_pagination.html.twig
  • @KnpPaginator/Pagination/bulma_pagination.html.twig
  • @KnpPaginator/Pagination/semantic_ui_pagination.html.twig
  • @KnpPaginator/Pagination/materialize_pagination.html.twig
  • @KnpPaginator/Pagination/tailwindcss_pagination.html.twig

Additional sortable templates

That could be used out of the box in knp_paginator.template.sortable key:

  • @KnpPaginator/Pagination/sortable_link.html.twig (by default)
  • @KnpPaginator/Pagination/twitter_bootstrap_v3_sortable_link.html.twig
  • @KnpPaginator/Pagination/twitter_bootstrap_v4_font_awesome_sortable_link.html.twig
  • @KnpPaginator/Pagination/semantic_ui_sortable_link.html.twig

Usage examples:

Controller

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 including
  • ModelCriteria - Propel ORM query
  • array with Solarium_Client and Solarium_Query_Select as elements
// App\Controller\ArticleController.php

public function listAction(EntityManagerInterface $em, PaginatorInterface $paginator, Request $request)
{
    $dql   = "SELECT a FROM AcmeMainBundle:Article a";
    $query = $em->createQuery($dql);

    $pagination = $paginator->paginate(
        $query, /* query NOT result */
        $request->query->getInt('page', 1), /*page number*/
        10 /*limit per page*/
    );

    // parameters to template
    return $this->render('article/list.html.twig', ['pagination' => $pagination]);
}

View

{# 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{% if pagination.isSorted(['a.date', 'a.time']) %} class="sorted"{% endif %}>
            {{ 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>

Translation in view

For translating the following text:
* %foo% name with translation key table_header_name. The translation is in the domain messages.
* {0} No author|{1} Author|[2,Inf] Authors with translation key table_header_author. The translation is in the domain messages.

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>

Dependency Injection

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.

Lazy service

The knp_paginator service will be created lazily if the package symfony/proxy-manager-bridge is installed.

For more information about lazy services, consult the Symfony documentation on dependency injection.

XML configuration example
<?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>

Troubleshooting

  • Make sure the translator is activated in your Symfony config:
framework:
    translator: { fallbacks: ['%locale%'] }
  • If your locale is not available, create your own translation file in translations/KnpPaginatorBundle.en.yml (substitute "en" for your own language code if needed). Then add these lines:
label_next: Next
label_previous: Previous

Maintainers

Please read this post first.

This library is maintained by the following people (alphabetically sorted) :
- @garak
- @polc

Copyright (c) 2011 Knplabs

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
  • By garak, 10 months ago
  • By garak, 10 months ago
  • By garak, 10 months ago
  • Allow page limit to be configured (#629)
    By web-flow, 10 months ago
  • Bugfix: Use array_replace with query parameters (#628)
    By web-flow, 10 months ago
  • Add limit to number of pages (#627)
    By web-flow, 10 months ago
  • Merge pull request #625 from garethbraid89/master
    By web-flow, 11 months ago
  • Updated fontawesome sortable reference
    By Gareth, 11 months ago
  • fix: link to Knp Pager Component (#622)
    By web-flow, 11 months ago
  • Delete old doc, not needed anymore
    By web-flow, 1 year ago
  • remove default params from paginator links (#617)
    By web-flow, 1 year ago
  • Make it possible to check if a list is sorted on multiple columns (#613)
    By web-flow, 1 year ago
  • Merge pull request #610 from garak/remove-deprecated-check
    By web-flow, 1 year ago
  • remove useless check for UrlGenerator constant
    By garak, 1 year ago
  • prepare v5.1.1
    By garak, 1 year ago
  • Merge pull request #608 from jbdelhommeau/fix-searchword-trans
    By web-flow, 1 year ago
  • fix: add searchword translation
    By jbdelhommeau, 1 year ago
  • Merge pull request #606 from garak/fix-setusedroute
    By web-flow, 1 year ago
  • fix argument type in setUsedRoute
    By garak, 1 year ago
  • do not distribute .php_cs file
    By garak, 1 year ago
  • prepare release v5.1.0
    By garak, 1 year ago
  • Merge pull request #603 from garak/fix-processor
    By web-flow, 1 year ago
  • fix type hint in sortable. Fix issue #599
    By garak, 1 year ago
  • Merge pull request #602 from garak/fix-types
    By web-flow, 1 year ago
  • add some missing types
    By garak, 1 year ago
  • Merge pull request #601 from garak/fix-templates
    By web-flow, 1 year ago
  • Merge pull request #597 from garak/remove-framework-bundle
    By web-flow, 1 year ago
  • Merge pull request #600 from umpirsky/fix/issue-598
    By web-flow, 1 year ago
  • fix templates
    By garak, 1 year ago
  • Fix issue #598
    By umpirsky, 1 year ago