add generic pagination template (#14939)

This commit is contained in:
Frédéric Péters 2017-12-26 20:52:48 +01:00
parent c3bcea469e
commit ef4a43df28
4 changed files with 123 additions and 3 deletions

View File

@ -80,3 +80,8 @@ http://www.gnome.org/.
gadjo/static/css/header-03.jpeg is copied from let's encrypt website, licensed
under Mozilla Public License Version 2.0, see their repository at
https://github.com/letsencrypt/website.git.
The querystring template tag is originally from django-tables2, copyright (c)
2011, Bradley Ayers, copyright (c) 2008, Michael Elsdörfer, published under
the MIT license.
https://raw.githubusercontent.com/jieter/django-tables2/master/LICENSE

View File

@ -539,13 +539,13 @@ p.paginator span {
}
p.paginator span.this-page {
background: #0066CC;
border-color: #0066CC;
background: #5B616B;
border-color: #5B616B;
color: white;
}
p.paginator span.this-page + a {
border-left-color: #0066CC;
border-left-color: #5B616B;
}
p.paginator a:hover {

View File

@ -0,0 +1,41 @@
{% load gadjo %}
{% comment %}
Pagination bar
Expected context variables:
- request: django request object
- page_obj: Paginator page object
- page_key (optional): name of page parameter (default: page)
- anchor (optional): anchor to use in links
{% endcomment %}
{% if page_obj.paginator.num_pages > 1 %}
{% with page_key=page_key|default:"page" %}
{% spaceless %}
<p class="paginator">
{% if page_obj.number > 1 %}
{% if page_obj.previous_page_number != 1 %}
<a href="{% querystring page_key=1 %}{{ anchor }}">1</a>
{% endif %}
{% endif %}
{% if page_obj.has_previous %}
<a href="{% querystring page_key=page_obj.previous_page_number %}{{ anchor }}">{{ page_obj.previous_page_number }}</a>
{% endif %}
<span class="this-page">{{ page_obj.number }}</span>
{% if page_obj.has_next %}
<a href="{% querystring page_key=page_obj.next_page_number %}{{ anchor }}">{{ page_obj.next_page_number }}</a>
{% endif %}
{% if page_obj.number != page_obj.paginator.num_pages %}
{% if page_obj.next_page_number != page_obj.paginator.num_pages %}
<a href="{% querystring page_key=page_obj.paginator.num_pages %}{{ anchor }}">{{ page_obj.paginator.num_pages }}</a>
{% endif %}
{% endif %}
</p>
{% endspaceless %}
{% endwith %}
{% endif %}

View File

@ -1,7 +1,13 @@
from collections import OrderedDict
import re
from xstatic.main import XStatic
from django import template
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.utils.html import escape
from django.utils.http import urlencode
register = template.Library()
@ -34,3 +40,71 @@ def xstatic(modname, filename):
return base_url.get(filename)
return settings.STATIC_URL + 'xstatic/' + filename
# {% querystring %} bits originally from django-tables2.
kwarg_re = re.compile(r"(?:(.+)=)?(.+)")
def token_kwargs(bits, parser):
"""
Based on Django's `~django.template.defaulttags.token_kwargs`, but with a
few changes:
- No legacy mode.
- Both keys and values are compiled as a filter
"""
if not bits:
return {}
kwargs = OrderedDict()
while bits:
match = kwarg_re.match(bits[0])
if not match or not match.group(1):
return kwargs
key, value = match.groups()
del bits[:1]
kwargs[parser.compile_filter(key)] = parser.compile_filter(value)
return kwargs
class QuerystringNode(template.Node):
def __init__(self, updates, removals):
super(QuerystringNode, self).__init__()
self.updates = updates
self.removals = removals
def render(self, context):
if not 'request' in context:
raise ImproperlyConfigured('Missing django.core.context_processors.request')
params = dict(context['request'].GET)
for key, value in self.updates.items():
key = key.resolve(context)
value = value.resolve(context)
if key not in ("", None):
params[key] = value
for removal in self.removals:
params.pop(removal.resolve(context), None)
return escape("?" + urlencode(params, doseq=True))
@register.tag
def querystring(parser, token):
"""
Creates a URL (containing only the querystring [including "?"]) derived
from the current URL's querystring, by updating it with the provided
keyword arguments.
Example (imagine URL is ``/abc/?gender=male&name=Brad``)::
{% querystring "name"="Ayers" "age"=20 %}
?name=Ayers&gender=male&age=20
{% querystring "name"="Ayers" without "gender" %}
?name=Ayers
"""
bits = token.split_contents()
tag = bits.pop(0)
updates = token_kwargs(bits, parser)
# ``bits`` should now be empty of a=b pairs, it should either be empty, or
# have ``without`` arguments.
if bits and bits.pop(0) != "without":
raise TemplateSyntaxError("Malformed arguments to '%s'" % tag)
removals = [parser.compile_filter(bit) for bit in bits]
return QuerystringNode(updates, removals)