diff --git a/README.txt b/README.txt index c390dc3..1eac6b4 100644 --- a/README.txt +++ b/README.txt @@ -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 diff --git a/gadjo/static/css/gadjo.scss b/gadjo/static/css/gadjo.scss index e0513c6..70c9e1b 100644 --- a/gadjo/static/css/gadjo.scss +++ b/gadjo/static/css/gadjo.scss @@ -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 { diff --git a/gadjo/templates/gadjo/pagination.html b/gadjo/templates/gadjo/pagination.html new file mode 100644 index 0000000..810f23f --- /dev/null +++ b/gadjo/templates/gadjo/pagination.html @@ -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 %} +

+ {% if page_obj.number > 1 %} + {% if page_obj.previous_page_number != 1 %} + 1 + … + {% endif %} + {% endif %} + + {% if page_obj.has_previous %} + {{ page_obj.previous_page_number }} + {% endif %} + + {{ page_obj.number }} + + {% if page_obj.has_next %} + {{ page_obj.next_page_number }} + {% endif %} + {% if page_obj.number != page_obj.paginator.num_pages %} + {% if page_obj.next_page_number != page_obj.paginator.num_pages %} + … + {{ page_obj.paginator.num_pages }} + {% endif %} + {% endif %} +

+{% endspaceless %} +{% endwith %} +{% endif %} diff --git a/gadjo/templatetags/gadjo.py b/gadjo/templatetags/gadjo.py index e042baa..de525ff 100644 --- a/gadjo/templatetags/gadjo.py +++ b/gadjo/templatetags/gadjo.py @@ -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)