"""
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)