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 <paul.eggleton@linux.intel.com>
This commit is contained in:
Paul Eggleton 2013-02-19 15:08:03 +00:00
parent 430ae4f90e
commit 02f7ca3b2d
7 changed files with 147 additions and 42 deletions

View File

@ -99,27 +99,8 @@
</div> </div>
{% if is_paginated %} {% if is_paginated %}
<div class="pagination pagination-centered"> {% load pagination %}
<ul> {% pagination page_obj %}
{% if page_obj.has_previous %}
<li><a href="?page={{ page_obj.previous_page_number }}">prev</a></li>
{% else %}
<li class="disabled"><a href="#">prev</a></li>
{% endif %}
{% for i in paginator.page_range %}
{% if i == page_obj.number %}
<li class="active"><a href="#">{{ page_obj.number }}</a></li>
{% else %}
<li><a href="?page={{i}}">{{i}}</a></li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li><a href="?page={{ page_obj.next_page_number }}">next</a></li>
{% else %}
<li class="disabled"><a href="#">next</a></li>
{% endif %}
</ul>
</div>
{% endif %} {% endif %}
{% else %} {% else %}
<p>No matching layers in database.</p> <p>No matching layers in database.</p>

View File

@ -62,27 +62,8 @@
</table> </table>
{% if is_paginated %} {% if is_paginated %}
<div class="pagination pagination-centered"> {% load pagination %}
<ul> {% pagination page_obj %}
{% if page_obj.has_previous %}
<li><a href="?page={{ page_obj.previous_page_number }}">prev</a></li>
{% else %}
<li class="disabled"><a href="#">prev</a></li>
{% endif %}
{% for i in paginator.page_range %}
{% if i == page_obj.number %}
<li class="active"><a href="#">{{ page_obj.number }}</a></li>
{% else %}
<li><a href="?page={{i}}">{{i}}</a></li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li><a href="?page={{ page_obj.next_page_number }}">next</a></li>
{% else %}
<li class="disabled"><a href="#">next</a></li>
{% endif %}
</ul>
</div>
{% endif %} {% endif %}
{% else %} {% else %}
{% if search_keyword %} {% if search_keyword %}

View File

View File

@ -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)

View File

@ -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

57
pagination.html Normal file
View File

@ -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 %}
<div class="pagination pagination-centered">
<ul>
{% if page.has_previous %}
<li><a href="{% addurlparameter 'page' page.previous_page_number %}">prev</a></li>
{% else %}
<li class="disabled"><span>prev</span></li>
{% endif %}
{% for pnum in begin %}
{% if pnum == page.number %}
<li class="active"><a href="#">{{ page.number }}</a></li>
{% else %}
<li><a href="{% addurlparameter 'page' pnum %}">{{ pnum }}</a></li>
{% endif %}
{% endfor %}
{% if middle %}
<li class="disabled"><span>...</span></li>
{% for pnum in middle %}
{% if pnum == page.number %}
<li class="active"><span>{{ page.number }}</span></li>
{% else %}
<li><a href="{% addurlparameter 'page' pnum %}">{{ pnum }}</a></li>
{% endif %}
{% endfor %}
{% endif %}
{% if end %}
<li class="disabled"><span>...</span></li>
{% for pnum in end %}
{% if pnum == page.number %}
<li class="active"><span>{{ page.number }}</span></li>
{% else %}
<li><a href="{% addurlparameter 'page' pnum %}">{{ pnum }}</a></li>
{% endif %}
{% endfor %}
{% endif %}
{% if page.has_next %}
<li><a href="{% addurlparameter 'page' page.next_page_number %}">next</a></li>
{% else %}
<li class="disabled"><span>next</span></li>
{% endif %}
</ul>
</div>

View File

@ -108,6 +108,11 @@ MIDDLEWARE_CLASSES = (
'reversion.middleware.RevisionMiddleware', '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' ROOT_URLCONF = 'urls'
TEMPLATE_DIRS = ( TEMPLATE_DIRS = (