Code

Paginator Tag

This is a very basic inclusion tag which builds on the variables already set on the context when paginating with the generic object_list view to allow you to create pagination controls which display first/last page links and links for a number of pages adjacent to the current page.

The following additional context variables are created:

  • page_numbers: A list of page numbers (in ascending order) which should be displayed, including the current page number.
  • show_first: A boolean representing whether a first page link should be shown - this will be True if the first page number doesn't appear in page_numbers.
  • show_last: A boolean representing whether a last page link should be shown - this will be True if the last page number doesn't appear in page_numbers.

Sample Output

An object list with 7 pages, using the default number of adjacent links per page.

http://www.jonathanbuchanan.plus.com/images/paginatortag01.png
http://www.jonathanbuchanan.plus.com/images/paginatortag02.png
http://www.jonathanbuchanan.plus.com/images/paginatortag03.png
http://www.jonathanbuchanan.plus.com/images/paginatortag04.png

Usage

The tag can take a single argument, which specifies the number of adjacent page links. The default is 2.

{% if is_paginated %}<div class="paginator">{% paginator %}</div>{% endif %}
{% if is_paginated %}<div class="paginator">{% paginator 4 %}</div>{% endif %}

Code

For details on where this template tag code should be placed and how it can be used in your templates, please see http://www.djangoproject.com/documentation/templates_python/#extending-the-template-system

from django import template

register = template.Library()

def paginator(context, adjacent_pages=2):
    """
    To be used in conjunction with the object_list generic view.

    Adds pagination context variables for use in displaying first, adjacent and
    last page links in addition to those created by the object_list generic
    view.
    """
    page_numbers = [n for n in \
                    range(context["page"] - adjacent_pages, context["page"] + adjacent_pages + 1) \
                    if n > 0 and n <= context["pages"]]
    return {
        "hits": context["hits"],
        "results_per_page": context["results_per_page"],
        "page": context["page"],
        "pages": context["pages"],
        "page_numbers": page_numbers,
        "next": context["next"],
        "previous": context["previous"],
        "has_next": context["has_next"],
        "has_previous": context["has_previous"],
        "show_first": 1 not in page_numbers,
        "show_last": context["pages"] not in page_numbers,
    }

register.inclusion_tag("paginator.html", takes_context=True)(paginator)

Sample paginator.html:

{% spaceless %}
<span class="paginate-pages" onclick="Paginator.jumpToPage({{ pages }})" title="Page Jump">{{ pages }} Pages</span>
{% if show_first %}<span class="paginate-first"><a href="?page=1" title="First Page">&laquo;</a></span>{% endif %}
{% if has_previous %}<span class="paginate-previous"><a href="?page={{ previous }}" title="Previous Page">&lt;</a></span>{% endif %}
{% for num in page_numbers %}
  {% ifequal num page %}
    <span class="paginate-current" title="Current Page">{{ num }}</span>
  {% else %}
    <span class="paginate-link"><a href="?page={{ num }}" title="Page {{ num }}">{{ num }}</a></span>
  {% endifequal %}
{% endfor %}
{% if has_next %}<span class="paginate-next"><a href="?page={{ next }}" title="Next Page">&gt;</a></span>{% endif %}
{% if show_last %}<span class="paginate-last"><a href="?page={{ pages }}" title="Last Page">&raquo;</a></span>{% endif %}
{% endspaceless %}

Paginator Javascript object, as used by the above:

var Paginator =
{
    jumpToPage: function(pages)
    {
        var page = prompt("Enter a number between 1 and " + pages + " to jump to that page", "");
        if (page != undefined)
        {
            page = parseInt(page, 10)
            if (!isNaN(page) && page > 0 && page <= pages)
            {
                window.location.href = "?page=" + page;
            }
        }
    }
};

Sample paginator CSS, as used to style the sample output images:

.paginator { padding: .25em .25em .6em .25em; }
.paginate-pages { padding: 2px 3px; border: 1px solid #ddd; cursor: pointer; text-decoration: underline; }
.paginate-first, .paginate-last { padding: 2px 6px; border: 1px solid #ddd; font-weight: bold; }
.paginate-previous, .paginate-next { padding: 2px 3px; border: 1px solid #ddd; }
.paginate-link { padding: 2px 4px; border: 1px solid #ddd; }
.paginate-current { padding: 2px 4px; border: 1px solid #ddd; font-weight: bold; background:#417690; color:#f4f379; }
Last modified 7 years ago Last modified on 02/16/07 13:46:53