Navigation in django
You do not need an if to do that, have a look at the following code:
tags.py
@register.simple_tagdef active(request, pattern): import re if re.search(pattern, request.path): return 'active' return ''
urls.py
urlpatterns += patterns('', (r'/$', view_home_method, 'home_url_name'), (r'/services/$', view_services_method, 'services_url_name'), (r'/contact/$', view_contact_method, 'contact_url_name'),)
base.html
{% load tags %}{% url 'home_url_name' as home %}{% url 'services_url_name' as services %}{% url 'contact_url_name' as contact %}<div id="navigation"> <a class="{% active request home %}" href="{{ home }}">Home</a> <a class="{% active request services %}" href="{{ services }}">Services</a> <a class="{% active request contact %}" href="{{ contact }}">Contact</a></div>
that's it.for implementation details have a look at:
gnuvince.wordpress.com
110j.wordpress.com
I use template inheritance to customize navigation. For example:
base.html
<html> <head>...</head> <body> ... {% block nav %} <ul id="nav"> <li>{% block nav-home %}<a href="{% url 'home' %}">Home</a>{% endblock %}</li> <li>{% block nav-about %}<a href="{% url 'about' %}">About</a>{% endblock %}</li> <li>{% block nav-contact %}<a href="{% url 'contact' %}">Contact</a>{% endblock %}</li> </ul> {% endblock %} ... </body></html>
about.html
{% extends "base.html" %}{% block nav-about %}<strong class="nav-active">About</strong>{% endblock %}
I liked the cleanness of 110j above so I took most of it and refactored to solve the 3 problems I had with it:
- the regular expression wasmatching the 'home' url against allothers
- I needed multiple URLsmapped to one navigation tab, so Ineeded a more complex tag that takesvariable amount of parameters
- fixed some url problems
Here it is:
tags.py:
from django import templateregister = template.Library()@register.tagdef active(parser, token): args = token.split_contents() template_tag = args[0] if len(args) < 2: raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag return NavSelectedNode(args[1:])class NavSelectedNode(template.Node): def __init__(self, patterns): self.patterns = patterns def render(self, context): path = context['request'].path for p in self.patterns: pValue = template.Variable(p).resolve(context) if path == pValue: return "active" # change this if needed for other bootstrap version (compatible with 3.2) return ""
urls.py:
urlpatterns += patterns('', url(r'/$', view_home_method, {}, name='home_url_name'), url(r'/services/$', view_services_method, {}, name='services_url_name'), url(r'/contact/$', view_contact_method, {}, name='contact_url_name'), url(r'/contact/$', view_contact2_method, {}, name='contact2_url_name'),)
base.html:
{% load tags %}{% url home_url_name as home %}{% url services_url_name as services %}{% url contact_url_name as contact %}{% url contact2_url_name as contact2 %}<div id="navigation"> <a class="{% active request home %}" href="home">Home</a> <a class="{% active request services %}" href="services">Services</a> <a class="{% active request contact contact2 %}" href="contact">Contact</a></div>