page_link

  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
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
"""
To make page links like below:

Prev 1 ... 23 24 25 26 27 ...221 Next

Use like this , "bbs_posting_list" is the name of url 

{% page_link "bbs_posting_list" page pages %}

page_link.html:

{% load zsp_tags %}

{% if prev %}<a href="{% url url_name prev %}">Prev</a>{% endif %}

{% for i in page_numbers %}

    {% if forloop.first %}
        {% ifnotequal 1 i %}<a href="{% url url_name 1 %}">1</a>{% endifnotequal %}
        {% if omit_first %}...{% endif %}
    {% endif %}
    
    {% ifequal i page %}
        <a class="now">{{ i }}</a>
    {% else %}
        <a href="{% url url_name i %}">{{ i }}</a>
    {% endifequal %}
    
    {% if forloop.last %}
        {% if omit_last %}...{% endif %}
        {% ifnotequal pages i %}<a href="{% url url_name pages %}">{{ pages }}</a>{% endifnotequal %}
    {% endif %}
    
{% endfor %}

{% if next %}<a href="{% url url_name next %}">Next</a>{% endif %}

"""

from django import template

register = template.Library()

@register.inclusion_tag('page_link.html')
def page_link(url_name,page,pages,adjacent_pages=2):
    page_numbers=[n for n in \
                    range(page - adjacent_pages,page + adjacent_pages + 1) \
                    if n > 0 and n <= pages
                    ]
    try:
        [1,2].index(page_numbers[0])
        omit_first=False
    except ValueError:
        omit_first=True
        
    try:
        [pages-1,pages].index(page_numbers[-1])
        omit_last=False
    except ValueError:
        omit_last=True

    return {
    "url_name":url_name,
    "pages":pages,"page":page,"page_numbers":page_numbers,
    'omit_first':omit_first,'omit_last':omit_last,
    "prev":page!=1,"next":page!=pages
    }



"Default tags used by the template system, available to all templates."

from django.template import Node, NodeList, Template, Context, resolve_variable
from django.core.urlresolvers import reverse
from django.conf import settings


class URLNode(Node):
    def __init__(self, view_name, args, kwargs):
        self.view_name = view_name
        self.args = args
        self.kwargs = kwargs

    def render(self, context):
        from django.core.urlresolvers import reverse, NoReverseMatch
        args = [arg.resolve(context) for arg in self.args]
        kwargs = dict([(smart_str(k,'ascii'), v.resolve(context)) for k, v in self.kwargs.items()])


        def _reverse(url_name):
            return reverse(url_name,args=args, kwargs=kwargs)

        try:
            return _reverse(self.view_name)
        except NoReverseMatch:
            try:
                project_name = settings.SETTINGS_MODULE.split('.')[0]
                return _reverse(project_name + '.' + self.view_name)
            except NoReverseMatch:
                url_name = context.get(self.view_name,'')
                if url_name:
                    try:
                            return _reverse(url_name)
                    except NoReverseMatch:
                        try:
                            return _reverse(project_name + '.' + url_name)
                        except NoReverseMatch:
                            return ''
            return ''
            
def url(parser, token):
    """
    Returns an absolute URL matching given view with its parameters.

    This is a way to define links that aren't tied to a particular URL configuration::

        {% url path.to.some_view arg1,arg2,name1=value1 %}

    The first argument is a path to a view. It can be an absolute python path
    or just ``app_name.view_name`` without the project name if the view is
    located inside the project.  Other arguments are comma-separated values
    that will be filled in place of positional and keyword arguments in the
    URL. All arguments for the URL should be present.

    For example if you have a view ``app_name.client`` taking client's id and
    the corresponding line in a URLconf looks like this::

        ('^client/(\d+)/$', 'app_name.client')

    and this app's URLconf is included into the project's URLconf under some
    path::

        ('^clients/', include('project_name.app_name.urls'))

    then in a template you can create a link for a certain client like this::

        {% url app_name.client client.id %}

    The URL will look like ``/clients/client/123/``.
    """
    bits = token.contents.split(' ', 2)
    if len(bits) < 2:
        raise TemplateSyntaxError, "'%s' takes at least one argument (path to a view)" % bits[0]
    args = []
    kwargs = {}
    if len(bits) > 2:
        for arg in bits[2].split(','):
            if '=' in arg:
                k, v = arg.split('=', 1)
                k = k.strip()
                kwargs[k] = parser.compile_filter(v)
            else:
                args.append(parser.compile_filter(arg))
    return URLNode(bits[1], args, kwargs)
url = register.tag(url)

More like this

  1. Improved many-page pagination by dokterbob 3 years, 7 months ago
  2. Pagination/Filtering Alphabetically by zain 5 years, 1 month ago
  3. better paginator template tag by amitu 5 years, 6 months ago
  4. Page numbers with ... like in Digg by Ciantic 5 years ago
  5. Active page class for selected menu items by kunitoki 1 year, 6 months ago

Comments

(Forgotten your password?)