Skip to content

Instantly share code, notes, and snippets.

@sbaechler
Last active November 20, 2017 22:00
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save sbaechler/5636351 to your computer and use it in GitHub Desktop.
Save sbaechler/5636351 to your computer and use it in GitHub Desktop.
Django Template Tag for pretty pagination with the Foundation framework.
# -*- coding: utf-8 -*-
"""
Based on http://blog.localkinegrinds.com/2007/09/06/digg-style-pagination-in-django/
and http://djangosnippets.org/snippets/2680/
Recreated by Haisheng HU <hanson2010@gmail.com> on Jun 3, 2012
Updated by Simon Bächler for Foundation on Apr. 28, 2015
http://foundation.zurb.com/docs/components/pagination.html
"""
from django import template
register = template.Library()
LEADING_PAGE_RANGE_DISPLAYED = TRAILING_PAGE_RANGE_DISPLAYED = 10
LEADING_PAGE_RANGE = TRAILING_PAGE_RANGE = 8
NUM_PAGES_OUTSIDE_RANGE = 2
ADJACENT_PAGES = 4
def foundation_paginator(context, page_tag='page'):
"""
To be used in conjunction with the object_list generic view.
Adds pagination context variables for use in displaying leading, adjacent and
trailing page links in addition to those created by the object_list generic
view.
"""
paginator = context['paginator']
page_obj = context['page_obj']
pages = paginator.num_pages
page = page_obj.number
in_leading_range = in_trailing_range = False
pages_outside_leading_range = pages_outside_trailing_range = range(0)
if pages <= LEADING_PAGE_RANGE_DISPLAYED + NUM_PAGES_OUTSIDE_RANGE + 1:
in_leading_range = in_trailing_range = True
page_range = [n for n in range(1, pages + 1)]
elif page <= LEADING_PAGE_RANGE:
in_leading_range = True
page_range = [n for n in range(1, LEADING_PAGE_RANGE_DISPLAYED + 1)]
pages_outside_leading_range = [n + pages for n in range(0, -NUM_PAGES_OUTSIDE_RANGE, -1)]
elif page > pages - TRAILING_PAGE_RANGE:
in_trailing_range = True
page_range = [n for n in range(pages - TRAILING_PAGE_RANGE_DISPLAYED + 1, pages + 1)
if n > 0 and n <= pages]
pages_outside_trailing_range = [n + 1 for n in range(0, NUM_PAGES_OUTSIDE_RANGE)]
else:
page_range = [n for n in range(page - ADJACENT_PAGES, page + ADJACENT_PAGES + 1)
if n > 0 and n <= pages]
pages_outside_leading_range = [n + pages for n in range(0, -NUM_PAGES_OUTSIDE_RANGE, -1)]
pages_outside_trailing_range = [n + 1 for n in range(0, NUM_PAGES_OUTSIDE_RANGE)]
# Now try to retain GET params, except for 'page'
# Add 'django.core.context_processors.request' to settings.TEMPLATE_CONTEXT_PROCESSORS
request = context['request']
params = request.GET.copy()
if page_tag in params:
del(params[page_tag])
get_params = params.urlencode()
return {
'pages': pages,
'page': page,
'previous': page_obj.previous_page_number() if page_obj.has_previous() else "",
'next': page_obj.next_page_number() if page_obj.has_next() else "",
'has_previous': page_obj.has_previous(),
'has_next': page_obj.has_next(),
'page_range': page_range,
'in_leading_range': in_leading_range,
'in_trailing_range': in_trailing_range,
'pages_outside_leading_range': pages_outside_leading_range,
'pages_outside_trailing_range': pages_outside_trailing_range,
'get_params': get_params,
}
register.inclusion_tag("foundation_paginator.html", takes_context=True)(foundation_paginator)
"""
Create foundation_paginator.html in template folder as below. Then you can remix it and shine it by CSS.
<div class="pagination-centered">
<ul class="pagination">
<li class="arrow{% if not has_previous %} unavailable{% endif %}"><a href="{% if has_previous %}{% if get_params %}?{{ get_params }}&{% else %}?{% endif %}page={{ previous }}{% endif %}">&laquo;</a></li>
{% if not in_leading_range %}
{% for p in pages_outside_trailing_range %}
<li><a href="{% if get_params %}?{{ get_params }}&{% else %}?{% endif %}page={{ p }}">{{ p }}</a></li>
{% endfor %}
<li class="unavailable"><a href="">&hellip;</a></li>
{% endif %}
{% for p in page_range %}
<li{% if p == page %} class="current"{% endif %}><a href="{% if get_params %}?{{ get_params }}&{% else %}?{% endif %}page={{ p }}">{{ p }}</a></li>
{% endfor %}
{% if not in_trailing_range %}
<li class="unavailable"><a href="">&hellip;</a></li>
{% for p in pages_outside_leading_range reversed %}
<li><a href="{% if get_params %}?{{ get_params }}&{% else %}?{% endif %}page={{ p }}">{{ p }}</a></li>
{% endfor %}
{% endif %}
<li class="arrow{% if not has_next %} unavailable{% endif %}"><a href="{% if has_next %}{% if get_params %}?{{ get_params }}&{% else %}?{% endif %}page={{ next }}{% endif %}">&raquo;</a></li>
</ul>
</div>
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment