Skip to content

Commit

Permalink
add new option to enhance first page link
Browse files Browse the repository at this point in the history
  • Loading branch information
garak committed Sep 30, 2024
1 parent f334d9e commit 437b124
Show file tree
Hide file tree
Showing 21 changed files with 112 additions and 91 deletions.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ chapter of the documentation.

## Requirements:

- Knp Pager component `>=2.0`.
- 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.

Expand Down Expand Up @@ -71,19 +71,23 @@ public function registerBundles()

### Configuration example

You can configure default query parameter names and templates
You can configure default query parameter names and templates, and a few other options:

#### YAML:
```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_page_1_link: 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
Expand All @@ -101,14 +105,18 @@ use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigura
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_page_1_link' => 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
Expand Down
2 changes: 2 additions & 0 deletions config/paginator.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@

<service id="Knp\Bundle\PaginatorBundle\Twig\Extension\PaginationRuntime">
<argument type="service" id="knp_paginator.helper.processor" />
<argument type="string">%knp_paginator.page_name%</argument>
<argument>%knp_paginator.remove_page_1_link%</argument>
<tag name="twig.runtime" />
</service>
</services>
Expand Down
3 changes: 3 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ public function getConfigTreeBuilder(): TreeBuilder
->booleanNode('convert_exception')
->defaultFalse()
->end()
->booleanNode('remove_page_1_link')
->defaultFalse()
->end()
->end()
;

Expand Down
2 changes: 2 additions & 0 deletions src/DependencyInjection/KnpPaginatorExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public function load(array $configs, ContainerBuilder $container): void
$container->setParameter('knp_paginator.template.sortable', $config['template']['sortable']);
$container->setParameter('knp_paginator.page_range', $config['page_range']);
$container->setParameter('knp_paginator.page_limit', $config['page_limit']);
$container->setParameter('knp_paginator.page_name', $config['default_options']['page_name']);
$container->setParameter('knp_paginator.remove_page_1_link', $config['remove_page_1_link']);

$paginatorDef = $container->getDefinition('knp_paginator');
$paginatorDef->addMethodCall('setDefaultPaginatorOptions', [[
Expand Down
12 changes: 4 additions & 8 deletions src/Helper/Processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,10 @@
*/
final class Processor
{
private UrlGeneratorInterface $router;

private TranslatorInterface $translator;

public function __construct(UrlGeneratorInterface $router, TranslatorInterface $translator)
{
$this->router = $router;
$this->translator = $translator;
public function __construct(
private readonly UrlGeneratorInterface $router,
private readonly TranslatorInterface $translator
) {
}

/**
Expand Down
6 changes: 1 addition & 5 deletions src/Pagination/SlidingPagination.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ final class SlidingPagination extends AbstractPagination implements SlidingPagin
{
private ?string $route = null;

/** @var array<string, mixed> */
private array $params;

private int $pageRange = 5;

private ?int $pageLimit = null;
Expand All @@ -34,9 +31,8 @@ final class SlidingPagination extends AbstractPagination implements SlidingPagin
/**
* @param array<string, mixed> $params
*/
public function __construct(array $params)
public function __construct(private array $params)
{
$this->params = $params;
}

public function setUsedRoute(?string $route): void
Expand Down
6 changes: 1 addition & 5 deletions src/Subscriber/SlidingPaginationSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,11 @@ final class SlidingPaginationSubscriber implements EventSubscriberInterface
/** @var array<string, mixed> */
private array $params = [];

/** @var array<string, mixed> */
private array $options;

/**
* @param array<string, mixed> $options
*/
public function __construct(array $options)
public function __construct(private readonly array $options)
{
$this->options = $options;
}

public function onKernelRequest(RequestEvent $event): void
Expand Down
12 changes: 4 additions & 8 deletions src/Templating/PaginationHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,10 @@
*/
final class PaginationHelper extends Helper
{
protected PhpEngine $templating;

protected Processor $processor;

public function __construct(Processor $processor, PhpEngine $templating)
{
$this->processor = $processor;
$this->templating = $templating;
public function __construct(
private readonly Processor $processor,
private readonly PhpEngine $templating
) {
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/Twig/Extension/PaginationExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Knp\Bundle\PaginatorBundle\Twig\Extension;

use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;

final class PaginationExtension extends AbstractExtension
Expand All @@ -16,6 +17,7 @@ public function getFunctions(): array
new TwigFunction('knp_pagination_rel_links', [PaginationRuntime::class, 'rel_links'], $options),
new TwigFunction('knp_pagination_sortable', [PaginationRuntime::class, 'sortable'], $options),
new TwigFunction('knp_pagination_filter', [PaginationRuntime::class, 'filter'], $options),
new TwigFunction('knp_pagination_query', [PaginationRuntime::class, 'getQueryParams']),
];
}
}
28 changes: 23 additions & 5 deletions src/Twig/Extension/PaginationRuntime.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

final class PaginationRuntime implements RuntimeExtensionInterface
{
private Processor $processor;

public function __construct(Processor $processor)
{
$this->processor = $processor;
public function __construct(
private readonly Processor $processor,
private readonly string $pageName = 'page',
private readonly bool $skipFirstPageLink = false,
) {
}

/**
Expand Down Expand Up @@ -107,4 +107,22 @@ public function filter(
$this->processor->filter($pagination, $fields, $options ?? [], $params ?? [])
);
}

/**
* @param array<string, mixed> $query
* @param int $page
* @return array<string, mixed>
*/
public function getQueryParams(array $query, int $page): array
{
if ($page === 1 && $this->skipFirstPageLink) {
if (isset($query[$this->pageName])) {
unset($query[$this->pageName]);
}

return $query;
}

return array_merge($query, [$this->pageName => $page]);
}
}
16 changes: 8 additions & 8 deletions templates/Pagination/bulma_pagination.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@
{% if pageCount > 1 %}
<nav class="{{ classes|join(' ') }}" role="navigation" aria-label="pagination">
{% if previous is defined %}
<a rel="prev" class="pagination-previous" href="{{ path(route, query|merge({(pageParameterName): previous})) }}">{{ 'label_previous'|trans({}, 'KnpPaginatorBundle') }}</a>
<a rel="prev" class="pagination-previous" href="{{ path(route, knp_pagination_query(query, previous)) }}">{{ 'label_previous'|trans({}, 'KnpPaginatorBundle') }}</a>
{% else %}
<a class="pagination-previous" disabled>{{ 'label_previous'|trans({}, 'KnpPaginatorBundle') }}</a>
{% endif %}

{% if next is defined %}
<a rel="next" class="pagination-next" href="{{ path(route, query|merge({(pageParameterName): next})) }}">{{ 'label_next'|trans({}, 'KnpPaginatorBundle') }}</a>
<a rel="next" class="pagination-next" href="{{ path(route, knp_pagination_query(query, next)) }}">{{ 'label_next'|trans({}, 'KnpPaginatorBundle') }}</a>
{% else %}
<a class="pagination-next" disabled>{{ 'label_next'|trans({}, 'KnpPaginatorBundle') }}</a>
{% endif %}

<ul class="pagination-list">
<li>
{% if current == first %}
<a class="pagination-link is-current" aria-label="Page {{ current }}" aria-current="page" href="{{ path(route, query|merge({(pageParameterName): first})) }}">1</a>
<a class="pagination-link is-current" aria-label="Page {{ current }}" aria-current="page" href="{{ path(route, knp_pagination_query(query, first)) }}">1</a>
{% else %}
<a class="pagination-link" href="{{ path(route, query|merge({(pageParameterName): first})) }}">1</a>
<a class="pagination-link" href="{{ path(route, knp_pagination_query(query, first)) }}">1</a>
{% endif %}
</li>

Expand All @@ -43,9 +43,9 @@
{% if first != page and page != last %}
<li>
{% if page == current %}
<a class="pagination-link is-current" aria-label="Page {{ current }}" aria-current="page" href="{{ path(route, query|merge({(pageParameterName): page})) }}">{{ page }}</a>
<a class="pagination-link is-current" aria-label="Page {{ current }}" aria-current="page" href="{{ path(route, knp_pagination_query(query, page)) }}">{{ page }}</a>
{% else %}
<a class="pagination-link" aria-label="Goto page {{ page }}" href="{{ path(route, query|merge({(pageParameterName): page})) }}">{{ page }}</a>
<a class="pagination-link" aria-label="Goto page {{ page }}" href="{{ path(route, knp_pagination_query(query, page)) }}">{{ page }}</a>
{% endif %}
</li>
{% endif %}
Expand All @@ -59,9 +59,9 @@

<li>
{% if current == last %}
<a class="pagination-link is-current" aria-label="Page {{ current }}" aria-current="page" href="{{ path(route, query|merge({(pageParameterName): last})) }}">{{ last }}</a>
<a class="pagination-link is-current" aria-label="Page {{ current }}" aria-current="page" href="{{ path(route, knp_pagination_query(query, last)) }}">{{ last }}</a>
{% else %}
<a class="pagination-link" href="{{ path(route, query|merge({(pageParameterName): last})) }}">{{ last }}</a>
<a class="pagination-link" href="{{ path(route, knp_pagination_query(query, last)) }}">{{ last }}</a>
{% endif %}
</li>
</ul>
Expand Down
14 changes: 7 additions & 7 deletions templates/Pagination/foundation_v5_pagination.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<ul class="pagination">
{% if previous is defined %}
<li class="arrow">
<a rel="prev" href="{{ path(route, query|merge({(pageParameterName): previous})) }}">&laquo; {{ 'label_previous'|trans({}, 'KnpPaginatorBundle') }}</a>
<a rel="prev" href="{{ path(route, knp_pagination_query(query, previous)) }}">&laquo; {{ 'label_previous'|trans({}, 'KnpPaginatorBundle') }}</a>
</li>
{% else %}
<li class="arrow unavailable">
Expand All @@ -33,11 +33,11 @@

{% if startPage > 1 %}
<li>
<a href="{{ path(route, query|merge({(pageParameterName): 1})) }}">1</a>
<a href="{{ path(route, knp_pagination_query(query, 1)) }}">1</a>
</li>
{% if startPage == 3 %}
<li>
<a href="{{ path(route, query|merge({(pageParameterName): 2})) }}">2</a>
<a href="{{ path(route, knp_pagination_query(query, 2)) }}">2</a>
</li>
{% elseif startPage != 2 %}
<li class="unavailable">
Expand All @@ -49,7 +49,7 @@
{% for page in pagesInRange %}
{% if page != current %}
<li>
<a href="{{ path(route, query|merge({(pageParameterName): page})) }}">
<a href="{{ path(route, knp_pagination_query(query, page)) }}">
{{ page }}
</a>
</li>
Expand All @@ -69,20 +69,20 @@
</li>
{% else %}
<li>
<a href="{{ path(route, query|merge({(pageParameterName): (pageCount - 1)})) }}">
<a href="{{ path(route, knp_pagination_query(query, (pageCount - 1))) }}">
{{ pageCount - 1 }}
</a>
</li>
{% endif %}
{% endif %}
<li>
<a href="{{ path(route, query|merge({(pageParameterName): pageCount})) }}">{{ pageCount }}</a>
<a href="{{ path(route, knp_pagination_query(query, pageCount)) }}">{{ pageCount }}</a>
</li>
{% endif %}

{% if next is defined %}
<li class="arrow">
<a rel="next" href="{{ path(route, query|merge({(pageParameterName): next})) }}">
<a rel="next" href="{{ path(route, knp_pagination_query(query, next)) }}">
{{ 'label_next'|trans({}, 'KnpPaginatorBundle') }} &nbsp;&raquo;
</a>
</li>
Expand Down
14 changes: 7 additions & 7 deletions templates/Pagination/foundation_v6_pagination.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

{% if previous is defined %}
<li class="pagination-previous">
<a rel="prev" href="{{ path(route, query|merge({(pageParameterName): previous})) }}">
<a rel="prev" href="{{ path(route, knp_pagination_query(query, previous)) }}">
{{ 'label_previous'|trans({}, 'KnpPaginatorBundle') }}
</a>
</li>
Expand All @@ -17,11 +17,11 @@

{% if startPage > 1 %}
<li>
<a href="{{ path(route, query|merge({(pageParameterName): 1})) }}">1</a>
<a href="{{ path(route, knp_pagination_query(query, 1)) }}">1</a>
</li>
{% if startPage == 3 %}
<li>
<a href="{{ path(route, query|merge({(pageParameterName): 2})) }}">2</a>
<a href="{{ path(route, knp_pagination_query(query, 2)) }}">2</a>
</li>
{% elseif startPage != 2 %}
<li class="ellipsis"></li>
Expand All @@ -31,7 +31,7 @@
{% for page in pagesInRange %}
{% if page != current %}
<li>
<a href="{{ path(route, query|merge({(pageParameterName): page})) }}">
<a href="{{ path(route, knp_pagination_query(query, page)) }}">
{{ page }}
</a>
</li>
Expand All @@ -46,20 +46,20 @@
<li class="ellipsis"></li>
{% else %}
<li>
<a href="{{ path(route, query|merge({(pageParameterName): (pageCount - 1)})) }}">
<a href="{{ path(route, knp_pagination_query(query, (pageCount - 1))) }}">
{{ pageCount - 1 }}
</a>
</li>
{% endif %}
{% endif %}
<li>
<a href="{{ path(route, query|merge({(pageParameterName): pageCount})) }}">{{ pageCount }}</a>
<a href="{{ path(route, knp_pagination_query(query, pageCount)) }}">{{ pageCount }}</a>
</li>
{% endif %}

{% if next is defined %}
<li class="pagination-next">
<a rel="next" href="{{ path(route, query|merge({(pageParameterName): next})) }}">
<a rel="next" href="{{ path(route, knp_pagination_query(query, next)) }}">
{{ 'label_next'|trans({}, 'KnpPaginatorBundle') }}
</a>
</li>
Expand Down
Loading

0 comments on commit 437b124

Please sign in to comment.