{"id":14983916,"url":"https://github.com/knplabs/knppaginatorbundle","last_synced_at":"2025-05-14T22:05:33.224Z","repository":{"id":1030897,"uuid":"859126","full_name":"KnpLabs/KnpPaginatorBundle","owner":"KnpLabs","description":"SEO friendly Symfony paginator to sort and paginate","archived":false,"fork":false,"pushed_at":"2025-05-02T08:14:57.000Z","size":767,"stargazers_count":1799,"open_issues_count":13,"forks_count":343,"subscribers_count":51,"default_branch":"master","last_synced_at":"2025-05-14T22:04:25.585Z","etag":null,"topics":["paginator","php","seo","symfony","symfony-bundle","twig"],"latest_commit_sha":null,"homepage":"http://knplabs.com/en/blog/knp-paginator-reborn","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KnpLabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2010-08-24T13:51:40.000Z","updated_at":"2025-05-05T05:26:13.000Z","dependencies_parsed_at":"2024-04-28T17:32:17.419Z","dependency_job_id":"5220541e-e2ae-454e-8483-d08a8f8aae08","html_url":"https://github.com/KnpLabs/KnpPaginatorBundle","commit_stats":{"total_commits":468,"total_committers":193,"mean_commits":"2.4248704663212437","dds":0.8525641025641025,"last_synced_commit":"1a00f88149d25418bd99d8954eba951f04cc3acf"},"previous_names":[],"tags_count":52,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KnpLabs%2FKnpPaginatorBundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KnpLabs%2FKnpPaginatorBundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KnpLabs%2FKnpPaginatorBundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KnpLabs%2FKnpPaginatorBundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KnpLabs","download_url":"https://codeload.github.com/KnpLabs/KnpPaginatorBundle/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254235687,"owners_count":22036962,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["paginator","php","seo","symfony","symfony-bundle","twig"],"created_at":"2024-09-24T14:08:10.255Z","updated_at":"2025-05-14T22:05:33.149Z","avatar_url":"https://github.com/KnpLabs.png","language":"PHP","readme":"# Intro to KnpPaginatorBundle\n\nFriendly Symfony paginator to paginate everything\n\n[![Build Status](https://github.com/KnpLabs/KnpPaginatorBundle/workflows/Build/badge.svg)](https://github.com/KnpLabs/KnpPaginatorBundle/actions)\n\nGenerally this bundle is based on [Knp Pager component][knp_component_pager]. This\ncomponent introduces a different way of pagination handling. You can read more about the\ninternal logic on the given documentation link.\n\n**Note:** Keep **knp-components** in sync with this bundle. If you want to use\nolder version of KnpPaginatorBundle - use **v3.0** or **v4.X** tags in the repository which is\nsuitable to paginate **ODM MongoDB** and **ORM 2.0** queries\n\n## Latest updates\n\nFor details regarding changes please read about the [releases](https://github.com/KnpLabs/KnpPaginatorBundle/releases).\n\n## Requirements:\n\n- Knp Pager component `\u003e=4.4`.\n- KnpPaginatorBundle's master is compatible with Symfony `\u003e=6.4` versions.\n- Twig `\u003e=3.0` version is required if you use the Twig templating engine.\n\n## Features:\n\n- Does not require initializing specific adapters.\n- Can be customized in any way needed, etc.: pagination view, event subscribers.\n- Possibility to add custom filtering, sorting functionality depending on request parameters.\n- Separation of concerns, paginator is responsible for generating the pagination view only,\n  pagination view - for representation purposes.\n\n**Note:** using multiple paginators requires setting the **alias** in order to keep non\nconflicting parameters.\n\n## More detailed documentation:\n\n- Creating [custom pagination subscribers][doc_custom_pagination_subscriber]\n- [Customizing view][doc_templates] templates and arguments\n\n## Installation and configuration:\n\n### Pretty simple with [Composer](https://packagist.org), run\n\n```sh\ncomposer require knplabs/knp-paginator-bundle\n```\n\n### Add PaginatorBundle to your application kernel\n\nIf you don't use flex (you should), you need to manually enable bundle:\n\n```php\n// app/AppKernel.php\npublic function registerBundles()\n{\n    return [\n        // ...\n        new Knp\\Bundle\\PaginatorBundle\\KnpPaginatorBundle(),\n        // ...\n    ];\n}\n```\n\n\u003ca name=\"configuration\"\u003e\u003c/a\u003e\n\n### Configuration example\n\nYou can configure default query parameter names and templates, and a few other options:\n\n#### YAML:\n```yaml\nknp_paginator:\n    convert_exception: false            # throw a 404 exception when an invalid page is requested\n    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)\n    remove_first_page_param: false      # remove the page query parameter from the first page link\n    default_options:\n        page_name: page                 # page query parameter name\n        sort_field_name: sort           # sort field query parameter name\n        sort_direction_name: direction  # sort direction query parameter name\n        distinct: true                  # ensure distinct results, useful when ORM queries are using GROUP BY statements\n        filter_field_name: filterField  # filter field query parameter name\n        filter_value_name: filterValue  # filter value query parameter name\n        page_out_of_range: ignore       # ignore, fix, or throwException when the page is out of range\n        default_limit: 10               # default number of items per page\n    template:\n        pagination: '@KnpPaginator/Pagination/sliding.html.twig'     # sliding pagination controls template\n        rel_links: '@KnpPaginator/Pagination/rel_links.html.twig'    # \u003clink rel=...\u003e tags template\n        sortable: '@KnpPaginator/Pagination/sortable_link.html.twig' # sort link template\n        filtration: '@KnpPaginator/Pagination/filtration.html.twig'  # filters template\n```\n#### PHP:\n```php\n// config/packages/paginator.php\n\n\u003c?php declare(strict_types=1);\n\nuse Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ContainerConfigurator;\n\nreturn static function (ContainerConfigurator $configurator): void\n{\n    $configurator-\u003eextension('knp_paginator', [\n        'convert_exception' =\u003e false,             // throw a 404 exception when an invalid page is requested\n        'page_range' =\u003e 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\n        'remove_first_page_param' =\u003e false,       // remove the page query parameter from the first page link\n        'default_options' =\u003e [\n            'page_name' =\u003e 'page',                // page query parameter name\n            'sort_field_name' =\u003e 'sort',          // sort field query parameter name\n            'sort_direction_name' =\u003e 'direction', // sort direction query parameter name\n            'distinct' =\u003e true,                   // ensure distinct results, useful when ORM queries are using GROUP BY statements\n            'filter_field_name' =\u003e 'filterField', // filter field query parameter name\n            'filter_value_name' =\u003e 'filterValue',  // filter value query parameter name\n            'page_out_of_range' =\u003e 'ignore',      // ignore, fix, or throwException when the page is out of range\n            'default_limit' =\u003e 10                 // default number of items per page\n        ],\n        'template' =\u003e [\n            'pagination' =\u003e '@KnpPaginator/Pagination/sliding.html.twig',     // sliding pagination controls template\n            'rel_links' =\u003e '@KnpPaginator/Pagination/rel_links.html.twig',    // \u003clink rel=...\u003e tags template\n            'sortable' =\u003e '@KnpPaginator/Pagination/sortable_link.html.twig', // sort link template\n            'filtration' =\u003e '@KnpPaginator/Pagination/filtration.html.twig'   // filters template\n        ]\n    ]);\n};\n```\n\n#### Additional pagination templates\nThat could be used out of the box in `knp_paginator.template.pagination` key:\n\n* `@KnpPaginator/Pagination/sliding.html.twig` (by default)\n* `@KnpPaginator/Pagination/bootstrap_v5_pagination.html.twig`\n* `@KnpPaginator/Pagination/twitter_bootstrap_v4_pagination.html.twig`\n* `@KnpPaginator/Pagination/twitter_bootstrap_v3_pagination.html.twig`\n* `@KnpPaginator/Pagination/twitter_bootstrap_pagination.html.twig`\n* `@KnpPaginator/Pagination/foundation_v6_pagination.html.twig`\n* `@KnpPaginator/Pagination/foundation_v5_pagination.html.twig`\n* `@KnpPaginator/Pagination/bulma_pagination.html.twig`\n* `@KnpPaginator/Pagination/semantic_ui_pagination.html.twig`\n* `@KnpPaginator/Pagination/materialize_pagination.html.twig`\n* `@KnpPaginator/Pagination/tailwindcss_pagination.html.twig`\n* `@KnpPaginator/Pagination/uikit_v3_pagination.html.twig`\n\n#### Sample rel link tag template\nThat could be used out of the box in `knp_paginator.template.rel_links` key:\n\n* `@KnpPaginator/Pagination/rel_links.html.twig` (by default)\n\n#### Additional sortable templates\nThat could be used out of the box in `knp_paginator.template.sortable` key:\n\n* `@KnpPaginator/Pagination/sortable_link.html.twig` (by default)\n* `@KnpPaginator/Pagination/bootstrap_v5_bi_sortable_link.html.twig`\n* `@KnpPaginator/Pagination/bootstrap_v5_fa_sortable_link.html.twig`\n* `@KnpPaginator/Pagination/bootstrap_v5_md_sortable_link.html.twig`\n* `@KnpPaginator/Pagination/twitter_bootstrap_v3_sortable_link.html.twig`\n* `@KnpPaginator/Pagination/twitter_bootstrap_v4_font_awesome_sortable_link.html.twig`\n* `@KnpPaginator/Pagination/twitter_bootstrap_v4_material_design_icons_sortable_link.html.twig`\n* `@KnpPaginator/Pagination/semantic_ui_sortable_link.html.twig`\n* `@KnpPaginator/Pagination/uikit_v3_sortable.html.twig`\n\n#### Additional filtration templates\nThat could be used out of the box in `knp_paginator.template.filtration` key:\n\n* `@KnpPaginator/Pagination/filtration.html.twig` (by default)\n* `@KnpPaginator/Pagination/bootstrap_v5_filtration.html.twig`\n* `@KnpPaginator/Pagination/twitter_bootstrap_v4_filtration.html.twig`\n\n## Usage examples:\n\n### Controller\n\nCurrently paginator can paginate:\n\n- `array`\n- `Doctrine\\DBAL\\Query\\QueryBuilder`\n- `Doctrine\\ORM\\Query`\n- `Doctrine\\ORM\\QueryBuilder`\n- `Doctrine\\ODM\\MongoDB\\Query\\Query`\n- `Doctrine\\ODM\\MongoDB\\Query\\Builder`\n- `Doctrine\\ODM\\PHPCR\\Query\\Query`\n- `Doctrine\\ODM\\PHPCR\\Query\\Builder\\QueryBuilder`\n- `Doctrine\\Common\\Collection\\ArrayCollection` - any Doctrine relation collection including\n- `ModelCriteria` - Propel ORM query\n- array with `Solarium_Client` and `Solarium_Query_Select` as elements\n\n```php\n// App\\Controller\\ArticleController.php\n\npublic function listAction(EntityManagerInterface $em, PaginatorInterface $paginator, Request $request)\n{\n    $dql   = \"SELECT a FROM AcmeMainBundle:Article a\";\n    $query = $em-\u003ecreateQuery($dql);\n\n    $pagination = $paginator-\u003epaginate(\n        $query, /* query NOT result */\n        $request-\u003equery-\u003egetInt('page', 1), /* page number */\n        10 /* limit per page */\n    );\n\n    // parameters to template\n    return $this-\u003erender('article/list.html.twig', ['pagination' =\u003e $pagination]);\n}\n```\n\n### View\n\n#### In `\u003chead\u003e`:\n\n```twig\n{# rel links for pagination #}\n{{ knp_pagination_rel_links(pagination) }}\n```\n\n#### In `\u003cbody\u003e`:\n\n```twig\n{# total items count #}\n\u003cdiv class=\"count\"\u003e\n    {{ pagination.getTotalItemCount }}\n\u003c/div\u003e\n\u003ctable\u003e\n    \u003ctr\u003e\n        {# sorting of properties based on query components #}\n        \u003cth\u003e{{ knp_pagination_sortable(pagination, 'Id', 'a.id') }}\u003c/th\u003e\n        \u003cth{% if pagination.isSorted('a.title') %} class=\"sorted\"{% endif %}\u003e\n            {{ knp_pagination_sortable(pagination, 'Title', 'a.title') }}\n        \u003c/th\u003e\n        \u003cth{% if pagination.isSorted(['a.date', 'a.time']) %} class=\"sorted\"{% endif %}\u003e\n            {{ knp_pagination_sortable(pagination, 'Release', ['a.date', 'a.time']) }}\n        \u003c/th\u003e\n    \u003c/tr\u003e\n\n    {# table body #}\n    {% for article in pagination %}\n        \u003ctr {% if loop.index is odd %}class=\"color\"{% endif %}\u003e\n            \u003ctd\u003e{{ article.id }}\u003c/td\u003e\n            \u003ctd\u003e{{ article.title }}\u003c/td\u003e\n            \u003ctd\u003e{{ article.date | date('Y-m-d') }}, {{ article.time | date('H:i:s') }}\u003c/td\u003e\n        \u003c/tr\u003e\n    {% endfor %}\n\u003c/table\u003e\n{# display navigation #}\n\u003cdiv class=\"navigation\"\u003e\n    {{ knp_pagination_render(pagination) }}\n\u003c/div\u003e\n```\n\n### Translation in view\nFor translating the following text:\n* `%foo% name` with translation key `table_header_name`. The translation is in the domain `messages`.\n* `{0} No author|{1} Author|[2,Inf] Authors` with translation key `table_header_author`. The translation is in the domain `messages`.\n\ntranslationCount and translationParameters can be combined.\n\n```twig\n\u003ctable\u003e\n    \u003ctr\u003e\n       {# sorting of properties based on query components #}\n       \u003cth\u003e{{ knp_pagination_sortable(pagination, 'Id'|trans({foo:'bar'},'messages'), 'a.id' )|raw }}\u003c/th\u003e\n       \u003cth{% if pagination.isSorted('a.Title') %} class=\"sorted\"{% endif %}\u003e{{ knp_pagination_sortable(pagination, 'Title', 'a.title')|raw }}\u003c/th\u003e\n       \u003cth\u003e{{ knp_pagination_sortable(pagination, 'Author'|trans({}, 'messages'), 'a.author' )|raw }}\u003c/th\u003e\n    \u003c/tr\u003e\n\n    \u003c!-- Content of the table --\u003e\n\u003c/table\u003e\n```\n\n### Adding translation files\nYou can also override translations by creating a translation file in the following name format: `domain.locale.format`.\nSo, to create a translation file for this bundle you need to create for instance `KnpPaginatorBundle.tr.yaml` file under `project_root/translations/`\nand add your translations there:\n```yaml\nlabel_previous: \"Önceki\"\nlabel_next: \"Sonraki\"\nfilter_searchword: \"Arama kelimesi\"\n```\nIf you set default translation for configuration accordingly:\n```yaml\nframework:\n    default_locale: tr\n```\nSymfony will pick it automatically.\n\n### Dependency Injection\n\nYou can automatically inject a paginator service into another service by using the `knp_paginator.injectable` DIC tag.\nThe tag takes one optional argument `paginator`, which is the ID of the paginator service that should be injected.\nIt defaults to `knp_paginator`.\n\nThe class that receives the KnpPaginator service must implement `Knp\\Bundle\\PaginatorBundle\\Definition\\PaginatorAwareInterface`.\nIf you're too lazy you can also just extend the `Knp\\Bundle\\PaginatorBundle\\Definition\\PaginatorAware` base class.\n\n\u003e **⚠ Warning** using `PaginatorAwareInterface` is discouraged, and could be removed in a future version. You should not rely on setter\n\u003e injection, but only on proper constructor injection. Using Symfony built-in autowiring mechanism is the suggested way to go.\n\n#### Lazy service\n\nThe `knp_paginator` service will be created lazily if the package `symfony/proxy-manager-bridge` is installed.\n\nFor more information about lazy services, consult the [Symfony documentation on dependency injection](https://symfony.com/doc/current/service_container/lazy_services.html).\n\n###### XML configuration example\n\n```xml\n\u003c?xml version=\"1.0\" ?\u003e\n\n\u003ccontainer xmlns=\"http://symfony.com/schema/dic/services\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n    xsi:schemaLocation=\"http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd\"\u003e\n\n    \u003cparameters\u003e\n        \u003cparameter key=\"my_bundle.paginator_aware.class\"\u003eMyBundle\\Repository\\PaginatorAwareRepository\u003c/parameter\u003e\n    \u003c/parameters\u003e\n\n    \u003cservices\u003e\n        \u003cservice id=\"my_bundle.paginator_aware\" class=\"my_bundle.paginator_aware.class\"\u003e\n            \u003ctag name=\"knp_paginator.injectable\" paginator=\"knp_paginator\" /\u003e\n        \u003c/service\u003e\n    \u003c/services\u003e\n\u003c/container\u003e\n```\n\n[knp_component_pager]: https://github.com/KnpLabs/knp-components/blob/master/docs/pager/intro.md \"Knp Pager component introduction\"\n[doc_custom_pagination_subscriber]: https://github.com/KnpLabs/KnpPaginatorBundle/tree/master/docs/custom_pagination_subscribers.md \"Custom pagination subscribers\"\n[doc_templates]: https://github.com/KnpLabs/KnpPaginatorBundle/tree/master/docs/templates.md \"Customizing Pagination templates\"\n\n## Troubleshooting\n\n- Make sure the translator is activated in your Symfony config:\n\n```yaml\nframework:\n    translator: { fallbacks: ['%locale%'] }\n```\n\n- If your locale is not available, create your own translation file in\n  `translations/KnpPaginatorBundle.en.yml` (substitute \"en\" for your own language code if needed).\n  Then add these lines:\n\n```yaml\nlabel_next: Next\nlabel_previous: Previous\n```\n\n- Note that `\u003crel\u003e` links are only meaningful when using pagination, they are not relevant to sorting or filtering.\n\n## Maintainers\n\nPlease read [this post](https://knplabs.com/en/blog/news-for-our-foss-projects-maintenance) first.\n\nThis library is maintained by the following people (alphabetically sorted) :\n- @garak\n- @polc\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknplabs%2Fknppaginatorbundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fknplabs%2Fknppaginatorbundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknplabs%2Fknppaginatorbundle/lists"}