django-endless-pagination-de / endless_pagination /

from django.template import Context, loader

from endless_pagination import settings, utils

# preload page templates
PAGE_TEMPLATE = loader.get_template("endless/page_link.html")
CURRENT_TEMPLATE = loader.get_template("endless/current_link.html")

class EndlessPage(object):
    A page link representation.
    Interesting attributes:
        - *self.number*: the page number
        - *self.label*: the label of the link (normally the page number as string)
        - *self.url*: the url of the page (strting with "?")
        - *self.path*: the path of the page
        - *self.is_current*: return True if page is the current page displayed
        - *self.is_first*: return True if page is the first page
        - *self.is_last*:  return True if page is the last page
    def __init__(self, request, number, current_number, total_number, label=None):
        self.number = number
        self.label = unicode(number) if label is None else label
        self.is_current = number == current_number
        self.is_first = number == 1
        self.is_last = number == total_number
        self.url = utils.get_querystring_for_page(request, number)
        self.path = "%s%s" % (request.path, self.url)

    def __unicode__(self):
        Render the page as a link.
        context_instance = Context({'page': self})
        template = CURRENT_TEMPLATE if self.is_current else PAGE_TEMPLATE
        return template.render(context_instance)
class PageList(object):
    A sequence of endless pages.
    def __init__(self, request, page):
        self._request = request
        self._page = page
    def __getitem__(self, value):
        # type conversion is needed beacuse in templates django performs a 
        # dictionary lookup before the attribute lokups 
        # (when a dot is encountered)
            value = int(value)
        except (TypeError, ValueError):
            # a TypeError says to django to continue with an attribute lookup
            raise TypeError
        if 1 <= value <= len(self): 
            return EndlessPage(self._request, value, self._page.number, len(self))
        raise IndexError("page list index out of range")
    def __len__(self):
        The length of the sequence is the total number of pages.
        return self._page.paginator.num_pages
    def __iter__(self):
        Iterate over all the endless pages (from first to last).
        for i in range(len(self)):
            yield self[i+1]
    def __unicode__(self):
        Return digg-style pagination (by default).
        The callable *settings.PAGE_LIST_CALLABLE* can be used to customize
        the pages that are displayed.
        The callable takes the current page number and the total number of pages
        and must return a sequence of page numbers that will be displayed.
        The sequence can contain other values:
            - *"previous"*: will display the previous page in that position
            - *"next"*: will display the next page in that position
            - *None*: a separator will be displayed in that position
        Here is an example of custom calable that displays previous page, then
        first page, then a separator, then current page, then next page::
            def get_page_numbers(current_page, num_pages):
                return ("previous", 1, None, current_page, "next")
        If *settings.PAGE_LIST_CALLABLE* is None an internal callable is used,
        generating a digg-style pagination.
        if len(self) > 1:
            pages_callable = settings.PAGE_LIST_CALLABLE or utils.get_page_numbers
            pages = []
            for i in pages_callable(self._page.number, len(self)):
                if i is None:
                elif i == "previous":
                elif i == "next":
            context = {'pages': pages}
            return loader.render_to_string("endless/show_pages.html", context)
        return u""
    def current(self):
        Return current page.
        return self[self._page.number]
    def first(self):
        Return first page.
        return self[1]
    def last(self):
        Return last page.
        return self[len(self)]
    def previous(self):
        Return previous page or an empty string if current page is the first.
        if self._page.has_previous():
            return EndlessPage(self._request, self._page.previous_page_number(), 
                self._page.number, len(self), label=settings.PREVIOUS_LABEL)
        return u""
    def next(self):
        Return next page or an empty string if current page is the last.
        if self._page.has_next():
            return EndlessPage(self._request, self._page.next_page_number(), 
                self._page.number, len(self), label=settings.NEXT_LABEL)
        return u""