Version 0.1 alive and kicking!
[django-pagination.git] / pagination / templatetags / pagination_tags.py
1 try:
2     set
3 except NameError:
4     from sets import Set as set
5 from django import template
6 from pagination.registration import get_registry, default_pagination
7 registry = get_registry()
8 from django.db.models.query import QuerySet
9 from django.core.paginator import QuerySetPaginator, InvalidPage
10 #from django.template.loader import render_to_string
11
12 register = template.Library()
13
14 def do_autopaginate(parser, token):
15     split = token.split_contents()
16     if len(split) == 1:
17         return AutoPaginateNode()
18     elif len(split) == 2:
19         return AutoPaginateNode(queryset_var=split[1])
20     else:
21         raise template.TemplateSyntaxError('%r tag takes only one optional argument.' % split[0])
22
23 class AutoPaginateNode(template.Node):
24     def __init__(self, queryset_var=None):
25         if queryset_var:
26             self.queryset_var = template.Variable(queryset_var)
27         else:
28             self.queryset_var = None
29
30     def render(self, context):
31         if self.queryset_var is not None:
32             try:
33                 key = self.queryset_var.var
34                 value = self.queryset_var.resolve(context)
35                 model = value.model
36                 pagination = registry.get_for_model(model)
37                 if pagination is None:
38                     pagination = default_pagination
39                 paginator = QuerySetPaginator(value, pagination)
40                 try:
41                     page_obj = paginator.page(context['request'].page)
42                 except:
43                     return u''
44                 context[key] = page_obj.object_list
45                 context['paginator'] = paginator
46                 context['page_obj'] = page_obj
47                 return u''
48             except template.VariableDoesNotExist:
49                 pass
50         for d in context:
51             for key, value in d.iteritems():
52                 if issubclass(value.__class__, QuerySet):
53                     model = value.model
54                     pagination = registry.get_for_model(model)
55                     if pagination is not None:
56                         paginator = QuerySetPaginator(value, pagination)
57                         try:
58                             page_obj = paginator.page(context['request'].page)
59                         except:
60                             return u''
61                         context[key] = page_obj.object_list
62                         context['paginator'] = paginator
63                         context['page_obj'] = page_obj
64                         return u''
65         return u''
66
67 def paginate(context, window=4):
68     paginator = context['paginator']
69     page_obj = context['page_obj']
70     page_range = paginator.page_range
71     first = set(page_range[:window])
72     last = set(page_range[-window:])
73     current_start = page_obj.number-1-window
74     if current_start < 0:
75         current_start = 0
76     current_end = page_obj.number-1+window
77     if current_end < 0:
78         current_end = 0
79     current = set(page_range[current_start:current_end])
80     pages = []
81     if len(first.intersection(current)) == 0:
82         pages.extend(sorted(list(first)))
83         pages.append(None)
84         pages.extend(sorted(list(current)))
85     else:
86         pages.extend(sorted(list(first.union(current))))
87     if len(current.intersection(last)) == 0:
88         pages.append(None)
89         pages.extend(sorted(list(last)))
90     else:
91         pages.extend(sorted(list(last.difference(current))))
92     return { 
93         'pages': pages,
94         'page_obj': page_obj,
95         'paginator': paginator,
96         'is_paginated': paginator.count > paginator.per_page,
97     }
98     
99 register.inclusion_tag('pagination/pagination.html', takes_context=True)(paginate)
100 register.tag('autopaginate', do_autopaginate)