Created
March 25, 2010 06:25
-
-
Save dahlia/343250 to your computer and use it in GitHub Desktop.
pager.py
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
*.pyc | |
.*.swp | |
MANIFEST |
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
""":mod:`pager` --- Pager interface for long length web application | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
This module provides the pager like following look: | |
.. code-block:: text | |
[1] 2 3 4 5 6 7 8 9 10 ... 123 | |
1 2 3 [4] 5 6 7 8 9 10 ... 123 | |
1 ... 53 54 55 56 57 [58] 59 60 61 62 ... 123 | |
1 ... 113 114 115 116 117 118 [119] 120 121 122 123 | |
1 ... 113 114 115 116 117 118 119 120 121 122 [123] | |
It can be used like following code with Jinja_: | |
.. sourcecode:: jinja | |
<ul class="pager"> | |
{% for flag, page in pager %} | |
<li class="{{ flag is number and '' or flag }}"> | |
<a href="/?page={{ page }}">{{ page }}</a> | |
</li> | |
{% endfor %} | |
</ul> | |
.. _Jinja: http://jinja.pocoo.org/ | |
""" | |
__author__ = 'Hong Minhee' | |
__author_email__ = 'minhee' '@' 'dahlia.kr' | |
__version__ = '0.1' | |
__all__ = ['Pager', 'pager'] | |
class Pager(object): | |
""":class:`Pager` class that is iterable. :class:`Pager` instances can be | |
looped with :keyword:`for` statements. | |
The length represents a maximum number of pages. | |
>>> list(Pager(7)) | |
[('selected', 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7)] | |
The selected_page represents a currently selected page number. Its default | |
value is just ``1``. | |
>>> list(Pager(7, selected_page=5)) | |
[(1, 1), (2, 2), (3, 3), (4, 4), ('selected', 5), (6, 6), (7, 7)] | |
>>> list(Pager(7, selected_page=7)) | |
[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), ('selected', 7)] | |
Last, the width represents how many page numbers are shown at once. First | |
and last page numbers are excluded in the width. | |
>>> list(Pager(8, 4, width=5)) | |
[(1, 1), (2, 2), (3, 3), ('selected', 4), (5, 5), ('last', 8)] | |
The form of sequence is ``[(flag_or_page, page), ...]``. In | |
``(flag, page)`` pair, the flag can be :const:`Pager.FIRST` (``"first"``), | |
:const:`Page.LAST` (``"last"``), :const:`Page.SELECTED` (``"selected"``) or | |
ordinal page number. | |
>>> list(Pager(100, 100, width=5)) # doctest: +NORMALIZE_WHITESPACE | |
[('first', 1), (96, 96), (97, 97), (98, 98), (99, 99), | |
('selected', 100)] | |
>>> list(Pager(100, 1, width=5)) | |
[('selected', 1), (2, 2), (3, 3), (4, 4), (5, 5), ('last', 100)] | |
>>> list(Pager(100, 50, width=5)) # doctest: +NORMALIZE_WHITESPACE | |
[('first', 1), (48, 48), (49, 49), ('selected', 50), (51, 51), | |
(52, 52), ('last', 100)] | |
Pager is iterable, so it can be used in :keyword:`for` loop. | |
>>> for typ, page in Pager(100, 50, width=5): | |
... if typ == Pager.LAST: | |
... print "...", | |
... if typ == Pager.SELECTED: | |
... print "[{0}]".format(page), | |
... else: | |
... print page, | |
... if typ == Pager.FIRST: | |
... print "...", | |
1 ... 48 49 [50] 51 52 ... 100 | |
:param length: total length of pages | |
:type length: :class:`numbers.Integral` | |
:param selected_page: currently selected page number. default value is ``1`` | |
:type selected_page: :class:`numbers.Integral` | |
:param width: pager's width. default value is :const:`DEFAULT_WIDTH` | |
:type width: :class:`numbers.Integral` | |
""" | |
#: Default width which is exactly ``10``. | |
DEFAULT_WIDTH = 10 | |
#: Flag value which is exactly ``'first'`` for first page. | |
FIRST = 'first' | |
#: Flag value which is exactly ``'last'`` for last page. | |
LAST = 'last' | |
#: Flag value which is exactly ``'selected'`` for selected page. | |
SELECTED = 'selected' | |
__slots__ = 'length', 'selected_page', 'width' | |
def __init__(self, length, selected_page=1, width=DEFAULT_WIDTH): | |
self.length = int(length) | |
self.selected_page = int(selected_page) | |
self.width = int(width) | |
def __iter__(self): | |
half = self.width / 2 | |
if self.length > self.width and self.selected_page > half + 2: | |
yield self.FIRST, 1 | |
i = self.length - self.width + 1 \ | |
if self.selected_page + half >= self.length \ | |
else self.selected_page - half | |
else: | |
i = 1 | |
to = min(i + self.width, 1 + self.length) | |
for i in xrange(i, to): | |
yield self.SELECTED if i == self.selected_page else i, i | |
if max(self.selected_page, to) < self.length: | |
yield self.LAST, self.length | |
pager = 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
from distutils.core import setup | |
import pager | |
setup( | |
name='pager343250', | |
version=pager.__version__, | |
author=pager.__author__, | |
author_email=pager.__author_email__, | |
license='Public Domain', | |
py_modules=['pager'] | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment