| 226 | class PageListNode(Node): |
| 227 | def __init__(self, surround=0, firstlast=False, urlprefix='?page=', template='pagelists/default.html'): |
| 228 | self.surround = surround |
| 229 | self.firstlast = firstlast |
| 230 | self.urlsuffix = "/" |
| 231 | if urlprefix.startswith('?'): |
| 232 | self.urlprefix = urlprefix |
| 233 | self.urlsuffix = "" |
| 234 | elif urlprefix.startswith('/'): |
| 235 | self.urlprefix = urlprefix |
| 236 | else: |
| 237 | self.urlprefix = '../'+urlprefix |
| 238 | self.template_name = template |
| 239 | |
| 240 | def render(self, context): |
| 241 | if self.surround: |
| 242 | surround_start = context['page'] - self.surround |
| 243 | surround_end = context['page'] + self.surround |
| 244 | if self.firstlast and surround_start <= 1: |
| 245 | surround_start = 2 |
| 246 | elif surround_start < 1: |
| 247 | surround_start = 1 |
| 248 | if self.firstlast and surround_end >= context['pages']: |
| 249 | surround_end = context['pages'] - 1 |
| 250 | elif surround_end > context['pages']: |
| 251 | surround_end = context['pages'] |
| 252 | page_list = range(surround_start, surround_end+1) |
| 253 | else: |
| 254 | if self.firstlast: |
| 255 | page_list = range(2, context['pages']) |
| 256 | else: |
| 257 | page_list = range(1, context['pages'] + 1) |
| 258 | page_index = [] |
| 259 | for page in page_list: |
| 260 | page_index.append({'number': page, 'link': self.urlprefix+str(page)+self.urlsuffix}) |
| 261 | tmpl_context = Context() |
| 262 | tmpl_context.update(context) |
| 263 | tmpl_context['page_index'] = page_index |
| 264 | tmpl_context['firstlast'] = self.firstlast |
| 265 | if self.firstlast: |
| 266 | tmpl_context['first_link'] = self.urlprefix+"1"+self.urlsuffix |
| 267 | tmpl_context['last_link'] = self.urlprefix+str(context['pages'])+self.urlsuffix |
| 268 | |
| 269 | try: |
| 270 | t = get_template(self.template_name) |
| 271 | return t.render(tmpl_context) |
| 272 | except: |
| 273 | if settings.TEMPLATE_DEBUG: |
| 274 | raise |
| 275 | else: |
| 276 | return '' |
| 277 | |
| 731 | def pagelist(parser, token): |
| 732 | """ |
| 733 | Lists an index of pages. |
| 734 | |
| 735 | This tag uses a template to display an index of pages. It requires ``page`` |
| 736 | and ``pages`` to be available in the context where it is used. These variables will |
| 737 | already be in the context if you are using the ``object_list`` generic |
| 738 | view. It can be used like this:: |
| 739 | |
| 740 | {% pagelist %} |
| 741 | |
| 742 | If it is it will output a list of all the pages with links. If you only |
| 743 | want a certain number of pages surrounding the current page on the list |
| 744 | then you can use ``surround`` followed by a number. For example:: |
| 745 | |
| 746 | {% pagelist surround 3 %} |
| 747 | |
| 748 | If you want the first and last pages to be displayed as well then you can |
| 749 | use ``firstlast true``. For example:: |
| 750 | |
| 751 | {% pagelist surround 3 firstlast true %} |
| 752 | |
| 753 | By default, pagelists assume that pages are specified by the GET variable |
| 754 | page, so any links it creates look like "?page=1". You can override this |
| 755 | and specify either absolute urls like "/stuff/list/page" or relative urls |
| 756 | like "page". These are specified using ``urlprefix``. For example:: |
| 757 | |
| 758 | {% pagelist urlprefix /stuff/list/page %} |
| 759 | |
| 760 | Another example:: |
| 761 | |
| 762 | {% pagelist urlprefix page %} |
| 763 | |
| 764 | These would create links that look like "/stuff/list/page1/" and "../page1/" |
| 765 | respectively. |
| 766 | |
| 767 | By default, pagelists are rendered via the template |
| 768 | ``pagelists/default.html``, but you can override this for a particular |
| 769 | pagelist using ``template``. For example:: |
| 770 | |
| 771 | {% pagelist template pagelists/mypagelist.html %} |
| 772 | |
| 773 | Creating the ``pagelists/default.html`` template is your responsibility; in |
| 774 | your template directory, just create a ``pagelists`` directory containing a |
| 775 | file ``default.html``. |
| 776 | |
| 777 | Pagelist templates are passed two context variables in addition to all the |
| 778 | context variables in the template that pagelist tag was used in. |
| 779 | |
| 780 | * ``firstlast``: Whether to display the first and last pages. |
| 781 | |
| 782 | * ``page_index``: A list of pages. Each page has two attributes: ``number``, |
| 783 | the page number and ``link``: the link to the page based on |
| 784 | ``urlprefix``. |
| 785 | |
| 786 | If ``firstlast`` is true, two more context variables are passed in. |
| 787 | |
| 788 | * ``first_link``: A link to the first page based on ``urlprefix``. |
| 789 | |
| 790 | * ``last_link``: A link to the last page based on ``urlprefix``. |
| 791 | |
| 792 | Here's a sample ``pagelists/default.html`` template:: |
| 793 | |
| 794 | <ul class="pagelist"> |
| 795 | {% if firstlast %}<li><a href="{{ first_link }}" title="First"><< First</a></li>{% endif %} |
| 796 | {% for other_page in page_index %} |
| 797 | <ol |
| 798 | {% ifequal other_page.number previous %}class="previous"{% endifequal %} |
| 799 | {% ifequal other_page.number page %}class="current"{% endifequal %} |
| 800 | {% ifequal other_page.number next %}class="next"{% endifequal %} |
| 801 | > |
| 802 | <a href="{{ other_page.link }}" title="Page {{ other_page.number }}"> |
| 803 | {{ other_page.number }} |
| 804 | </a> |
| 805 | </ol> |
| 806 | {% endfor %} |
| 807 | {% if firstlast %}<li><a href="{{ last_link }}" title="Last">Last >></a></li>{% endif %} |
| 808 | </ul> |
| 809 | """ |
| 810 | bits = token.contents.split() |
| 811 | kwargs = {} |
| 812 | is_key = True |
| 813 | for bit in bits[1:]: |
| 814 | if is_key: |
| 815 | key = bit |
| 816 | else: |
| 817 | if key == 'surround': |
| 818 | bit = int(bit) |
| 819 | elif key == 'firstlast': |
| 820 | bit = bit.lower() == 'true' |
| 821 | kwargs[key] = bit |
| 822 | is_key = not is_key |
| 823 | return PageListNode(**kwargs) |
| 824 | |
| 825 | pagelist = register.tag(pagelist) |
| 826 | |
| 827 | #@register.tag |