From 02f7ca3b2dea36c21341fec2986177bdd6402d06 Mon Sep 17 00:00:00 2001 From: Paul Eggleton Date: Tue, 19 Feb 2013 15:08:03 +0000 Subject: [PATCH] Improve pagination for recipe list Use a Django snippet to make pagination display a bit nicer (compressed form instead of showing all page numbers). In order to interact properly with GET requests, an additional snippet was required to add parameters to the URL (why doesn't Django provide this out of the box?). Signed-off-by: Paul Eggleton --- layerindex/index.html | 23 +-------- layerindex/recipes.html | 23 +-------- layerindex/templatetags/__init__.py | 0 layerindex/templatetags/addurlparameter.py | 29 +++++++++++ layerindex/templatetags/pagination.py | 52 ++++++++++++++++++++ pagination.html | 57 ++++++++++++++++++++++ settings.py | 5 ++ 7 files changed, 147 insertions(+), 42 deletions(-) create mode 100644 layerindex/templatetags/__init__.py create mode 100644 layerindex/templatetags/addurlparameter.py create mode 100644 layerindex/templatetags/pagination.py create mode 100644 pagination.html diff --git a/layerindex/index.html b/layerindex/index.html index 34a623d..a294c4f 100644 --- a/layerindex/index.html +++ b/layerindex/index.html @@ -99,27 +99,8 @@ {% if is_paginated %} - + {% load pagination %} + {% pagination page_obj %} {% endif %} {% else %}

No matching layers in database.

diff --git a/layerindex/recipes.html b/layerindex/recipes.html index 72021b0..9683998 100644 --- a/layerindex/recipes.html +++ b/layerindex/recipes.html @@ -62,27 +62,8 @@ {% if is_paginated %} - + {% load pagination %} + {% pagination page_obj %} {% endif %} {% else %} {% if search_keyword %} diff --git a/layerindex/templatetags/__init__.py b/layerindex/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/layerindex/templatetags/addurlparameter.py b/layerindex/templatetags/addurlparameter.py new file mode 100644 index 0000000..58a454a --- /dev/null +++ b/layerindex/templatetags/addurlparameter.py @@ -0,0 +1,29 @@ +# Borrowed from http://djangosnippets.org/snippets/361/ +# Original author: johan de taeye +# With modifications from Ludwik Trammer +# +# Adds GET parameters to the current URL + +from django.template import Library, Node, resolve_variable, TemplateSyntaxError, Variable + +register = Library() + +class AddParameter(Node): + def __init__(self, varname, value): + self.varname = Variable(varname) + self.value = Variable(value) + + def render(self, context): + req = Variable('request').resolve(context) + params = req.GET.copy() + params[self.varname.resolve(context)] = self.value.resolve(context) + return '%s?%s' % (req.path, params.urlencode()) + +def addurlparameter(parser, token): + from re import split + bits = split(r'\s+', token.contents, 2) + if len(bits) < 2: + raise TemplateSyntaxError, "'%s' tag requires two arguments" % bits[0] + return AddParameter(bits[1],bits[2]) + +register.tag('addurlparameter', addurlparameter) diff --git a/layerindex/templatetags/pagination.py b/layerindex/templatetags/pagination.py new file mode 100644 index 0000000..aa3175f --- /dev/null +++ b/layerindex/templatetags/pagination.py @@ -0,0 +1,52 @@ +# Borrowed from http://djangosnippets.org/snippets/2199/ +# +# Digg-like page numbering using inclusion tag + +from django import template + +register = template.Library() + +@register.inclusion_tag('pagination.html', takes_context=True) +def pagination(context, page, begin_pages=2, end_pages=2, before_current_pages=4, after_current_pages=4): + # Digg-like pages + before = max(page.number - before_current_pages - 1, 0) + after = page.number + after_current_pages + + begin = page.paginator.page_range[:begin_pages] + middle = page.paginator.page_range[before:after] + end = page.paginator.page_range[-end_pages:] + last_page_number = end[-1] + + def collides(firstlist, secondlist): + """ Returns true if lists collides (have same entries) + + >>> collides([1,2,3,4],[3,4,5,6,7]) + True + >>> collides([1,2,3,4],[5,6,7]) + False + """ + return any(item in secondlist for item in firstlist) + + # If middle and end has same entries, then end is what we want + if collides(middle, end): + end = range(max(page.number-before_current_pages, 1), last_page_number+1) + + middle = [] + + # If begin and middle ranges has same entries, then begin is what we want + if collides(begin, middle): + begin = range(1, min(page.number + after_current_pages, last_page_number)+1) + + middle = [] + + # If begin and end has same entries then begin is what we want + if collides(begin, end): + begin = range(1, last_page_number+1) + end = [] + + context.update({'page' : page, + 'begin' : begin, + 'middle' : middle, + 'end' : end}) + + return context diff --git a/pagination.html b/pagination.html new file mode 100644 index 0000000..4e08cb7 --- /dev/null +++ b/pagination.html @@ -0,0 +1,57 @@ +{% comment %} + + layerindex-web - pagination template + + Copyright (C) 2013 Intel Corporation + Licensed under the MIT license, see COPYING.MIT for details + +{% endcomment %} + +{% load addurlparameter %} + + diff --git a/settings.py b/settings.py index 53dac13..f5c154d 100644 --- a/settings.py +++ b/settings.py @@ -108,6 +108,11 @@ MIDDLEWARE_CLASSES = ( 'reversion.middleware.RevisionMiddleware', ) +from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS as TCP +TEMPLATE_CONTEXT_PROCESSORS = TCP + ( + 'django.core.context_processors.request', +) + ROOT_URLCONF = 'urls' TEMPLATE_DIRS = (