add generic pagination template (#14939)
This commit is contained in:
parent
c3bcea469e
commit
ef4a43df28
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 %}
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue