Why should I pass RequestContext to all my answers?

I want to highlight the current page in the navigation menu. Obviously, I need the menu to display a class such as β€œactive” when you are on your page. This is a classic problem and I have seen many solutions. My problem is that I hate them all and I think that not one of them is very DRY. For example:

@register.simple_tag def active(request, pattern): import re if re.search(pattern, request.path): return 'active' return '' ---- {% load tags %} <div id="navigation"> <a class="{% active request "^/about/" %}" href="/about/">About</a> <a class="{% active request "^/contact/" %}" href="/contact/">Contact</a> <a class="{% active request "^/services/" %}" href="/services/">Services</a> </div> 

The tag accepts your current request and url expression and returns "active" if you are currently on this page. Alternatively, this can be done with named views, not with URLs, but the principle is the same.

My main problem is that my navigation will be called up 99% of my views, and yet, to get the current request variable, I still parse the RequestContext for the template like this:

 def contact(request): # snip ... return render_to_response( 'contact.html', { 'myvar' : myvar }, context_instance=RequestContext(request)) 

Why do I need to add this context_instance line to each of my views when, possibly, all but one need a request variable to get the current url / view in order to highlight the active link? This seems terribly wet, especially for a feature that should be in the vast majority of django sites. I want the request to be enabled by default and be able to suppress it. I cannot find a way to do this in the middleware, since I cannot intercept the template before displaying it after the view has returned it.

Any suggestions?

+5
django django-templates django-views navigation
Jun 27 '09 at 7:37
source share
3 answers

Your intention makes sense, you will need RequestContext most of the time, and only occasionally can it be safely skipped for performance reasons. The solution is simple, instead of render_to_response use the direct_to_template shortcut:

 from django.views.generic.simple import direct_to_template def contact(request): # snip ... return direct_to_template(request, 'contact.html', { 'myvar' : myvar }) 

... or render_to decorator from django-annoying :

 from annoying.decorators import render_to @render_to('template.html') def foo(request): bar = Bar.object.all() return {'bar': bar} 
+16
Jun 27 '09 at 14:23
source share

You don’t have to do anything with the layout of your navigation to give the current a different style - there are declarative ways to do this with CSS.

See my answer here: Django: Is there a better way to boldly link to the current page link for an example.

+1
Jun 27 '09 at 7:42
source share

For future reference, you can use django-tabs to perform the desired OP.

0
Feb 10 '11 at
source share



All Articles