""" 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 %}Prev{% endif %} {% for i in page_numbers %} {% if forloop.first %} {% ifnotequal 1 i %}1{% endifnotequal %} {% if omit_first %}...{% endif %} {% endif %} {% ifequal i page %} {{ i }} {% else %} {{ i }} {% endifequal %} {% if forloop.last %} {% if omit_last %}...{% endif %} {% ifnotequal pages i %}{{ pages }}{% endifnotequal %} {% endif %} {% endfor %} {% if next %}Next{% 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)