返回排行榜

KnpLabs/KnpPaginatorBundle

PHPknplabs.com/en/blog/knp-paginator-reborn

SEO friendly Symfony paginator to sort and paginate

twigphppaginatorsymfonysymfony-bundleseo
Star 增长趋势
Star
1.8k
Forks
332
周增长
Issues
15
5001k1.5k
2023年1月2024年3月2025年5月2026年7月
制品库Packagistcomposer require knplabs/knppaginatorbundle
README

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 of pagination handling. You can read more about the internal logic on the given documentation link.

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 details regarding changes please read about the releases.

Requirements:

  • Knp Pager component >=4.4.
  • KnpPaginatorBundle's master is compatible with Symfony >=6.4 versions.
  • Twig >=3.0 version is required if you use the Twig templating engine.
  • If you want to use the provided templates, you need the Translation component too.

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, and a few other options:

YAML:

knp_paginator:
    convert_exception: false            # throw a 404 exception when an invalid page is requested
    page_range: 5                       # number of links shown 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)
    remove_first_page_param: false      # remove the page query parameter from the first page link
    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
        page_out_of_range: ignore       # ignore, fix, or throwException when the page is out of range
        default_limit: 10               # default number of items per page
    template:
        pagination: '@KnpPaginator/Pagination/sliding.html.twig'     # sliding pagination controls template
        rel_links: '@KnpPaginator/Pagination/rel_links.html.twig'    # <link rel=...> tags template
        sortable: '@KnpPaginator/Pagination/sortable_link.html.twig' # sort link template
        filtration: '@KnpPaginator/Pagination/filtration.html.twig'  # filters template

PHP:

// config/packages/paginator.php

<?php declare(strict_types=1);

use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $configurator): void
{
    $configurator->extension('knp_paginator', [
        'convert_exception' => false,             // throw a 404 exception when an invalid page is requested
        'page_range' => 5,                        // number of links shown in the pagination menu (e.g: you have 10 pages, a page_range of 3, on the 5th page you'll see links
        'remove_first_page_param' => false,       // remove the page query parameter from the first page link
        '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
            'page_out_of_range' => 'ignore',      // ignore, fix, or throwException when the page is out of range
            'default_limit' => 10                 // default number of items per page
        ],
        'template' => [
            'pagination' => '@KnpPaginator/Pagination/sliding.html.twig',     // sliding pagination controls template
            'rel_links' => '@KnpPaginator/Pagination/rel_links.html.twig',    // <link rel=...> tags 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/bootstrap_v5_pagination.html.twig
  • @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_v6_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
  • @KnpPaginator/Pagination/uikit_v3_pagination.html.twig

Sample rel link tag template

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

  • @KnpPaginator/Pagination/rel_links.html.twig (by default)

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/bootstrap_v5_bi_sortable_link.html.twig
  • @KnpPaginator/Pagination/bootstrap_v5_fa_sortable_link.html.twig
  • @KnpPaginator/Pagination/bootstrap_v5_md_sortable_link.html.twig
  • @KnpPaginator/Pagination/twitter_bootstrap_v3_sortable_link.html.twig
  • @KnpPaginator/Pagination/twitter_bootstrap_v4_font_awesome_sortable_link.html.twig
  • @KnpPaginator/Pagination/twitter_bootstrap_v4_material_design_icons_sortable_link.html.twig
  • @KnpPaginator/Pagination/semantic_ui_sortable_link.html.twig
  • @KnpPaginator/Pagination/uikit_v3_sortable.html.twig

Additional filtration templates

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

  • @KnpPaginator/Pagination/filtration.html.twig (by default)
  • @KnpPaginator/Pagination/bootstrap_v5_filtration.html.twig
  • @KnpPaginator/Pagination/twitter_bootstrap_v4_filtration.html.twig

Usage examples:

Controller

Currently paginator can paginate:

  • array
  • Doctrine\DBAL\Query\QueryBuilder
  • 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

In <head>:

{# rel links for pagination #}
{{ knp_pagination_rel_links(pagination) }}

In <body>:

{# 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>

Adding translation files

You can also override translations by creating a translation file in the following name format: domain.locale.format. So, to create a translation file for this bundle you need to create for instance KnpPaginatorBundle.tr.yaml file under project_root/translations/ and add your translations there:

label_previous: "Önceki"
label_next: "Sonraki"
filter_searchword: "Arama kelimesi"

If you set default translation for configuration accordingly:

framework:
    default_locale: tr

Symfony will pick it automatically.

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.

⚠ Warning using PaginatorAwareInterface is discouraged, and could be removed in a future version. You should not rely on setter injection, but only on proper constructor injection. Using Symfony built-in autowiring mechanism is the suggested way to go.

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
  • Note that <rel> links are only meaningful when using pagination, they are not relevant to sorting or filtering.

Maintainers

Please read this post first.

This library is maintained by the following people (alphabetically sorted) :

  • @garak
  • @polc
相关仓库
getgrav/grav

Modern, Crazy Fast, Ridiculously Easy and Amazingly Powerful Flat-File CMS powered by PHP, Markdown, Twig, and Symfony

PHPPackagistMIT Licensephpcms
getgrav.org
15.6k1.4k
twigphp/Twig

Twig, the flexible, fast, and secure template language for PHP

PHPPackagistBSD 3-Clause "New" or "Revised" Licensetwigphp
twig.symfony.com
8.4k1.3k
timber/timber

Create WordPress themes with beautiful OOP code and the Twig Template Engine

PHPPackagistMIT Licensetwigwordpress
timber.github.io/docs/
5.7k508
kimai/kimai

Kimai is the #1 open-source time-tracking application. From freelancers to companies and organisations - everyone can manage timesheets, generate reports, create invoices and so much more... Web-based multi-user application, available as On-Premise or SaaS version: https://www.kimai.org

PHPPackagistGNU Affero General Public License v3.0timetrackertimetracking
kimai.org
4.8k813
bolt/bolt

Bolt is a simple CMS written in PHP. It is based on Silex and Symfony components, uses Twig and either SQLite, MySQL or PostgreSQL.

PHPPackagistMIT Licensephpcms
4.1k794
picocms/Pico

Pico is a stupidly simple, blazing fast, flat file CMS.

PHPPackagistMIT Licensepicopicocms
picocms.org
3.9k608
craftcms/cms

Build bespoke content experiences with Craft.

PHPPackagistOthercmscraftcms
craftcms.com
3.6k705
cocur/slugify

Converts a string to a slug. Includes integrations for Symfony, Silex, Laravel, Zend Framework 2, Twig, Nette and Latte.

PHPPackagistMIT Licensephptwig
2.9k246
twigjs/twig.js

JS implementation of the Twig Templating Language

JavaScriptnpmBSD 2-Clause "Simplified" Licensetwigtwigjs
1.9k280
fxbois/web-mode

web template editing mode for emacs

Emacs LispGNU General Public License v3.0emacsemacs-lisp
web-mode.org
1.7k259
FOSSBilling/FOSSBilling

Empower your hosting business with FOSSBilling, the free and open-source solution for efficient billing and client management.

PHPPackagistApache License 2.0billingbootstrap
fossbilling.org
1.6k333
twigphp/Twig-extensions

Twig extensions

PHPPackagistMIT Licensephptwig
twig.symfony.com
1.4k269