path_match

 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
"""
Use this to set an li element to active.
examples:
<li{% path_match '^(<% url news year,month,day %>|<% url news_index %>)$' %}><a href=...
<li{% path_match '^/contact/$' %}< a href...
"""

from django import template
import re

register = template.Library()

MATCH_STRING = ' class="active"'

class PathMatchNode(template.Node):
    def __init__(self, template_string):
        self.template_string = template_string
    def render(self, context):
        regexp = template.Template(template_string=self.template_string).render(context)
        try:
            match = re.match(regexp, context['request'].path)
        except:
            match = False
        if match:
            return MATCH_STRING
        else:
            return ""

@register.tag('path_match')
def do_path_match(parser, token):
    try:
        tag_name, arg = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError, "%r tag requires a single regexp as argument" % token.contents.split()[0]
    if not (arg[0] == arg[-1] and arg[0] in ( '"', "'" )):
        raise template.TemplateSyntaxError, "%r tag requires a single regexp as argument" % tag_name
    norm = re.compile(r'\<% ([^%\>]*) %\>')
    template_string = norm.sub(ur'{% \1 %}', arg)[1:-1]
    return PathMatchNode(template_string)

Comments

fax8 (on August 22, 2008):

In order to use this you should create two files: an empty one called _init_.py and one containing the above code called path_match.py

Then put them into a folder called "templatetags" inserted at the application root (same level as views.py ).

Then before using the {% path_match %} tag you should load the tag definition by inserting {% load path_match %} in the template file in which you will use the path_match tag.

For more informations see http://www.djangobook.com/en/1.0/chapter10/#cn92

#

(Forgotten your password?)

You may use Markdown syntax here, but raw HTML will be removed.