Page numbers with ... like in Digg

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from django import template

register = template.Library()

@register.inclusion_tag('pagination.html')
def pagination(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(last_page_number - before_current_pages - after_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(before_current_pages + 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 = []
    
    return {'page' : page,
            'begin' : begin,
            'middle' : middle,
            'end' : end}
    

More like this

  1. Improved many-page pagination by dokterbob 2 years, 8 months ago
  2. Digg-like pagination by SmileyChris 3 years, 12 months ago
  3. better paginator template tag by amitu 4 years, 7 months ago
  4. Add querystring parameters to path (template tag) by spenoir 3 months, 4 weeks ago
  5. Pagination/Filtering Alphabetically by zain 4 years, 2 months ago

Comments

ramusus (on April 16, 2009):

What differences between your code and django_pagination app?

http://code.google.com/p/django-pagination/

#

stalker (on December 20, 2009):

IMHO, this code have some bad logic, I replaced line 28 with:

end = range(max(page.number-before_current_pages, 1), last_page_number+1)

and line 33 with:

begin = range(1, min(page.number + after_current_pages, last_page_number)+1)

Without those two changes, one can't access (in some cases) all pages with using only generated links

#

Ciantic (on January 20, 2010):

This is very much in use, and I would like to know when it fails if it fails...

But note that it is intended to drop entries if there are too many. When user selects entry from closer it will show the next entries, so they are not really gone.

#

dokterbob (on September 16, 2010):

Thanks for the snippet. I found stalker's patch to be useful, and I changed the code somewhat to make the full context of the tag's use available from within the template.

New version posted as snippet 2199.

#

(Forgotten your password?)