| 246 | class PageListNode(Node): |
| 247 | def __init__(self, surround=0, firstlast=False, urlprefix='?page=', template='pagelists/default.html'): |
| 248 | self.surround = surround |
| 249 | self.firstlast = firstlast |
| 250 | self.urlsuffix = "/" |
| 251 | if urlprefix.startswith('?'): |
| 252 | self.urlprefix = urlprefix |
| 253 | self.urlsuffix = "" |
| 254 | elif urlprefix.startswith('/'): |
| 255 | self.urlprefix = urlprefix |
| 256 | else: |
| 257 | self.urlprefix = '../'+urlprefix |
| 258 | self.template_name = template |
| 259 | |
| 260 | def render(self, context): |
| 261 | if self.surround: |
| 262 | surround_start = context['page'] - self.surround |
| 263 | surround_end = context['page'] + self.surround |
| 264 | if self.firstlast and surround_start <= 1: |
| 265 | surround_start = 2 |
| 266 | elif surround_start < 1: |
| 267 | surround_start = 1 |
| 268 | if self.firstlast and surround_end >= context['pages']: |
| 269 | surround_end = context['pages'] - 1 |
| 270 | elif surround_end > context['pages']: |
| 271 | surround_end = context['pages'] |
| 272 | page_list = range(surround_start, surround_end+1) |
| 273 | else: |
| 274 | if self.firstlast: |
| 275 | page_list = range(2, context['pages']) |
| 276 | else: |
| 277 | page_list = range(1, context['pages'] + 1) |
| 278 | page_index = [] |
| 279 | for page in page_list: |
| 280 | page_index.append({'number': page, 'link': self.urlprefix+str(page)+self.urlsuffix}) |
| 281 | tmpl_context = Context() |
| 282 | tmpl_context.update(context) |
| 283 | tmpl_context['page_index'] = page_index |
| 284 | tmpl_context['firstlast'] = self.firstlast |
| 285 | if self.firstlast: |
| 286 | tmpl_context['first_link'] = self.urlprefix+"1"+self.urlsuffix |
| 287 | tmpl_context['last_link'] = self.urlprefix+str(context['pages'])+self.urlsuffix |
| 288 | |
| 289 | try: |
| 290 | t = get_template(self.template_name) |
| 291 | return t.render(tmpl_context) |
| 292 | except: |
| 293 | if settings.TEMPLATE_DEBUG: |
| 294 | raise |
| 295 | else: |
| 296 | return '' |
| 297 | |
| 811 | def pagelist(parser, token): |
| 812 | """ |
| 813 | Lists an index of pages. |
| 814 | |
| 815 | This tag uses a template to display an index of pages. It requires ``page`` |
| 816 | and ``pages`` to be available in the context where it is used. These variables will |
| 817 | already be in the context if you are using the ``object_list`` generic |
| 818 | view. It can be used like this:: |
| 819 | |
| 820 | {% pagelist %} |
| 821 | |
| 822 | If it is it will output a list of all the pages with links. If you only |
| 823 | want a certain number of pages surrounding the current page on the list |
| 824 | then you can use ``surround`` followed by a number. For example:: |
| 825 | |
| 826 | {% pagelist surround 3 %} |
| 827 | |
| 828 | If you want the first and last pages to be displayed as well then you can |
| 829 | use ``firstlast true``. For example:: |
| 830 | |
| 831 | {% pagelist surround 3 firstlast true %} |
| 832 | |
| 833 | By default, pagelists assume that pages are specified by the GET variable |
| 834 | page, so any links it creates look like "?page=1". You can override this |
| 835 | and specify either absolute urls like "/stuff/list/page" or relative urls |
| 836 | like "page". These are specified using ``urlprefix``. For example:: |
| 837 | |
| 838 | {% pagelist urlprefix /stuff/list/page %} |
| 839 | |
| 840 | Another example:: |
| 841 | |
| 842 | {% pagelist urlprefix page %} |
| 843 | |
| 844 | These would create links that look like "/stuff/list/page1/" and "../page1/" |
| 845 | respectively. |
| 846 | |
| 847 | By default, pagelists are rendered via the template |
| 848 | ``pagelists/default.html``, but you can override this for a particular |
| 849 | pagelist using ``template``. For example:: |
| 850 | |
| 851 | {% pagelist template pagelists/mypagelist.html %} |
| 852 | |
| 853 | Creating the ``pagelists/default.html`` template is your responsibility; in |
| 854 | your template directory, just create a ``pagelists`` directory containing a |
| 855 | file ``default.html``. |
| 856 | |
| 857 | Pagelist templates are passed two context variables in addition to all the |
| 858 | context variables in the template that pagelist tag was used in. |
| 859 | |
| 860 | * ``firstlast``: Whether to display the first and last pages. |
| 861 | |
| 862 | * ``page_index``: A list of pages. Each page has two attributes: ``number``, |
| 863 | the page number and ``link``: the link to the page based on |
| 864 | ``urlprefix``. |
| 865 | |
| 866 | If ``firstlast`` is true, two more context variables are passed in. |
| 867 | |
| 868 | * ``first_link``: A link to the first page based on ``urlprefix``. |
| 869 | |
| 870 | * ``last_link``: A link to the last page based on ``urlprefix``. |
| 871 | |
| 872 | Here's a sample ``pagelists/default.html`` template:: |
| 873 | |
| 874 | <ol id="pagelist"> |
| 875 | {% if firstlast %}<li><a href="{{ first_link }}" title="First"><< First</a></li>{% endif %} |
| 876 | {% for other_page in page_index %} |
| 877 | <li |
| 878 | {% ifequal other_page.number previous %}class="previous"{% endifequal %} |
| 879 | {% ifequal other_page.number page %}class="current"{% endifequal %} |
| 880 | {% ifequal other_page.number next %}class="next"{% endifequal %} |
| 881 | > |
| 882 | <a href="{{ other_page.link }}" title="Page {{ other_page.number }}"> |
| 883 | {{ other_page.number }} |
| 884 | </a> |
| 885 | </li> |
| 886 | {% endfor %} |
| 887 | {% if firstlast %}<li><a href="{{ last_link }}" title="Last">Last >></a></li>{% endif %} |
| 888 | </ol> |
| 889 | """ |
| 890 | bits = token.contents.split() |
| 891 | kwargs = {} |
| 892 | is_key = True |
| 893 | for bit in bits[1:]: |
| 894 | if is_key: |
| 895 | key = bit |
| 896 | else: |
| 897 | if key == 'surround': |
| 898 | bit = int(bit) |
| 899 | elif key == 'firstlast': |
| 900 | bit = bit.lower() == 'true' |
| 901 | kwargs[key] = bit |
| 902 | is_key = not is_key |
| 903 | return PageListNode(**kwargs) |
| 904 | |
| 905 | pagelist = register.tag(pagelist) |
| 906 | |
| 907 | #@register.tag |