A gist for pagination in Twig, based on the total number of pages, the current page and some URL-settings. UIkit design.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% include 'modules/pagination.twig' with { | |
currentFilters: { | |
foo: 'bar', | |
}, | |
currentPage: 43, | |
paginationPath: '/news', | |
showAlwaysFirstAndLast: true, | |
lastPage: 75, | |
urlType: 'slash', | |
} %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% import _self as macros %} | |
{# | |
Source: http://dev.dbl-a.com/symfony-2-0/symfony2-and-twig-pagination/ | |
Source: https://gist.github.com/SimonSimCity/4594748 | |
Source: https://gist.github.com/Grawl/5ebe19aa808e9b4371938a697b1597e8 | |
Updated by: Simon Schick <simonsimcity@gmail.com> | |
Updated by: Daniil Pronin <mail@grawl.ru> | |
Parameters: | |
* currentFilters (array) : associative array that contains the current route-arguments | |
* currentPage (int) : the current page you are in | |
* paginationPath (string) : the route name to use for links | |
* showAlwaysFirstAndLast (bool) : Always show first and last link (just disabled) | |
* lastPage (int) : represents the total number of existing pages | |
* urlType (string) : 'query' (`/news?page=4`) or 'slash' (`/news/4`) a way to build URL | |
#} | |
{% set scope = { | |
currentFilters: currentFilters ?: {}, | |
currentPage: currentPage ?: 1, | |
paginationPath: paginationPath ?: '', | |
showAlwaysFirstAndLast: showAlwaysFirstAndLast, | |
lastPage: lastPage, | |
urlType: urlType ?: 'query', | |
} %} | |
{% macro url_with_query(url, query) %} | |
{{ url ~ '?' ~ query|url_encode }} | |
{% endmacro %} | |
{% macro pagination_url(scope, url, query) %} | |
{% import _self as macros %} | |
{% if scope.urlType == 'query' %} | |
{{ macros.url_with_query(url, query) }} | |
{% elseif scope.urlType == 'slash' %} | |
{% set query_string = query|merge({ page: null })|url_encode %} | |
{{ url }}/{{ query.page }}{{ query_string ? '?' ~ query_string }} | |
{% else %} | |
{{ url }} | |
{% endif %} | |
{% endmacro %} | |
{% macro content(scope) %} | |
{% import _self as macros %} | |
{# the number of first and last pages to be displayed #} | |
{% set extremePagesLimit = 3 %} | |
{# the number of pages that are displayed around the active page #} | |
{% set nearbyPagesLimit = 2 %} | |
{% if scope.currentPage > 1 %} | |
<li> | |
<a href='{{ macros.pagination_url(scope, scope.paginationPath, scope.currentFilters|merge({ | |
page: scope.currentPage - 1 | |
})) }}'> | |
{{ 'pagination.previous'|trans }} | |
</a> | |
</li> | |
{% for i in range(1, extremePagesLimit) if ( i < scope.currentPage - nearbyPagesLimit ) %} | |
<li> | |
<a href='{{ macros.pagination_url(scope, scope.paginationPath, scope.currentFilters|merge({ | |
page: i | |
})) }}'>{{ i }}</a> | |
</li> | |
{% endfor %} | |
{% if extremePagesLimit + 1 < scope.currentPage - nearbyPagesLimit %} | |
<li class='uk-disabled'> | |
<span>…</span> | |
</li> | |
{% endif %} | |
{% for i in range(scope.currentPage - nearbyPagesLimit, scope.currentPage - 1) if ( i > 0 ) %} | |
<li> | |
<a href='{{ macros.pagination_url(scope, scope.paginationPath, scope.currentFilters|merge({ | |
page: i | |
})) }}'>{{ i }}</a> | |
</li> | |
{% endfor %} | |
{% elseif scope.showAlwaysFirstAndLast %} | |
<li class='uk-disabled'> | |
<span>{{ 'pagination.previous'|trans }}</span> | |
</li> | |
{% endif %} | |
<li class='uk-active'> | |
<a href='{{ macros.pagination_url(scope, scope.paginationPath, scope.currentFilters|merge({ | |
page: scope.currentPage | |
})) }}'> | |
{{ scope.currentPage }} | |
</a> | |
</li> | |
{% if scope.currentPage < scope.lastPage %} | |
{% for i in range(scope.currentPage + 1, scope.currentPage + nearbyPagesLimit) | |
if ( i <= scope.lastPage ) | |
%} | |
<li> | |
<a href='{{ macros.pagination_url(scope, scope.paginationPath, scope.currentFilters|merge({ | |
page: i | |
})) }}'>{{ i }}</a> | |
</li> | |
{% endfor %} | |
{% if (scope.lastPage - extremePagesLimit) > (scope.currentPage + nearbyPagesLimit) %} | |
<li class='uk-disabled'> | |
<span>…</span> | |
</li> | |
{% endif %} | |
{% for i in range(scope.lastPage - extremePagesLimit + 1, scope.lastPage) | |
if ( i > scope.currentPage + nearbyPagesLimit ) | |
%} | |
<li> | |
<a href='{{ macros.pagination_url(scope, scope.paginationPath, scope.currentFilters|merge({ | |
page: i | |
})) }}'>{{ i }}</a> | |
</li> | |
{% endfor %} | |
<li> | |
<a href='{{ macros.pagination_url(scope, scope.paginationPath, scope.currentFilters|merge({ | |
page: scope.currentPage + 1 | |
})) }}'> | |
{{ 'pagination.next'|trans }} | |
</a> | |
</li> | |
{% elseif scope.showAlwaysFirstAndLast %} | |
<li class='uk-disabled'> | |
<span> | |
{{ 'pagination.next'|trans }} | |
</span> | |
</li> | |
{% endif %} | |
{% endmacro %} | |
{% spaceless %} | |
{% if scope.lastPage > 1 %} | |
<ul class='uk-pagination'> | |
{{ macros.content(scope) }} | |
</ul> | |
{% endif %} | |
{% endspaceless %} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment