Created
September 21, 2011 08:50
-
-
Save zhangsen/1231609 to your computer and use it in GitHub Desktop.
django-simple-pager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# This piece of code is in the public domain. | |
# <[email protected]> | |
# | |
#### the filter #### | |
def insert_ellipse(lst, ellipse=0): | |
'''Insert ellipse where it's not sequential | |
An ellipse is represented by @ellipse. | |
E.g.: | |
[1, 2, 5] -> [1, 2, 0, 5] | |
[1, 2, 4] -> [1, 2, 3, 4] | |
The last example is that if only one step is missing, just add it instead | |
of an ellipse. | |
''' | |
if len(lst) <= 1: | |
return list(lst[:]) | |
gap = lst[1] - lst[0] | |
if gap <= 1: | |
return [lst[0]] + insert_ellipse(lst[1:], ellipse) | |
elif gap == 2: | |
return [lst[0], lst[0] + 1] + insert_ellipse(lst[1:], ellipse) | |
else: | |
return [lst[0], ellipse] + insert_ellipse(lst[1:], ellipse) | |
@register.filter | |
def pick_pages(num_pages, current): | |
'''pick pages to display in the pager | |
It's like: 1 ... (x-2) (x-1) (x) (x+1) (x+2) ... N. | |
''' | |
ret = [] | |
for p in range(current - 2, current): | |
if p >= 1: | |
ret.append(p) | |
ret.append(current) | |
for p in range(current + 1, current + 3): | |
if p <= num_pages: | |
ret.append(p) | |
if ret[0] != 1: | |
ret.insert(0, 1) | |
if ret[-1] != num_pages: | |
ret.append(num_pages) | |
ret = insert_ellipse(ret) | |
return ret | |
#### template #### | |
{% if page.paginator.num_pages > 1 %} | |
<div class="pager"> | |
{% if page.number > 1 %} | |
<a href="{% add_get_param request 'page' page.previous_page_number %}"> | |
<span class="page-number prev">←prev</span> | |
</a> | |
{% endif %} | |
{% for p in page.paginator.num_pages|pick_pages:page.number %} | |
{% if p == page.number %} | |
<span class="page-number current">{{p}}</span> | |
{% else %}{% if p == 0 %} | |
<span class="page-number ellipse">…</span> | |
{% else %} | |
<a href="{% add_get_param request 'page' p %}"> | |
<span class="page-number">{{p}}</span> | |
</a> | |
{% endif %} | |
{% endif %} | |
{% endfor %} | |
{% if page.number < page.paginator.num_pages %} | |
<a href="{% add_get_param request 'page' page.next_page_number %}"> | |
<span class="page-number next">next→</span> | |
</a> | |
{% endif %} | |
</div> | |
{% endif %} | |
#### unittest / examples #### | |
def test_insert_ellipse(self): | |
for lst, result in ( | |
((0, 1, 3), [0, 1, 2, 3]), | |
((0, 1, 4), [0, 1, None, 4]), | |
): | |
self.assertEqual(insert_ellipse(lst, ellipse=None), result) | |
for lst, result in ( | |
((1,), [1]), | |
((1, 3, 5), [1, 2, 3, 4, 5]), | |
((3, 7), [3, 0, 7]), | |
): | |
self.assertEqual(points_utils.insert_ellipse(lst), result) | |
def test_filter_pick_pages(self): | |
for num_pages, current, output in ( | |
(3, 1, [1, 2, 3]), | |
(5, 1, [1, 2, 3, 4, 5]), | |
(5, 3, [1, 2, 3, 4, 5]), | |
(6, 1, [1, 2, 3, 0, 6]), | |
(6, 5, [1, 2, 3, 4, 5, 6]), | |
(6, 6, [1, 0, 4, 5, 6]), | |
(1, 1, [1]), | |
): | |
self.assertEqual(pick_pages(num_pages, current), output) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment