I understand that request.path will give me the current URL.
I am currently working on my base.html template with CSS tabs and I want the template to know which tab is currently "active" and pass class="active-tab" to an <a> tag.
So I wanted to do something like
<a href="{% url orders_list %}"
{% if request.path = reverse('orders_list') %}
class="active-tab"
{$ endif %}
>Orders</a>
But I'm sure you can't do that if comparison. I also only want the base (?) URL ignoring any GET parameters.
Any suggestions or tips also welcomed. Thanks in advance!
You can use a custom template tag
from django import template
register = template.Library()
@register.simple_tag
def active(request, pattern):
path = request.path
if path == pattern:
return 'active'
return ''
Then usage is sort of like this in your template:
{% load my_tags %}
{% url orders_list as orders %}
<li class="{% active request orders %}">
<a href="{{ orders }}"> Orders </a>
</li>
You can modify the template tag as you wish.
Building on Josh's answer, you can use a simple 'if' tag:
{% url 'orders_list' as orders_list_url %}
<a{% if request.path == orders_list_url %} class="active"{% endif %}
href="{{ orders_list_url }}">Orders</a>
A better version of the top answer would be to reverse the viewname:
{% url_active 'reverse_viewname' %}
This version doesn't require you to pass in the request. Instead, we indicate that the tag needs the context and then get the request from that.
from django import template
from django.core.urlresolvers import reverse
register = template.Library()
@register.simple_tag(takes_context=True)
def url_active(context, viewname):
request = context['request']
current_path = request.path
compare_path = reverse(viewname)
if current_path == compare_path:
return 'active'
else:
return ''
Inspired by cougar's answer:
$("ul.nav [href='"+window.location.pathname+"']").parents("li").addClass('active');
This solution is plain JS, and works for Bootstrap's navigation bar. For the OP's scenario one can use:
$("[href='"+window.location.pathname+"']").addClass('active-tab');
A solution with an if-then-else option:
from django import template
from django.template.base import Node, NodeList, TemplateSyntaxError
register = template.Library()
class IfCurrentViewNode(Node):
child_nodelists = ('nodelist_true', 'nodelist_false')
def __init__(self, view_name, nodelist_true, nodelist_false):
self.view_name = view_name
self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false
def __repr__(self):
return "<IfCurrentViewNode>"
def render(self, context):
view_name = self.view_name.resolve(context, True)
request = context['request']
if request.resolver_match.url_name == view_name:
return self.nodelist_true.render(context)
return self.nodelist_false.render(context)
def do_ifcurrentview(parser, token):
bits = token.split_contents()
if len(bits) < 2:
raise TemplateSyntaxError("'%s' takes at least one argument"
" (path to a view)" % bits[0])
view_name = parser.compile_filter(bits[1])
nodelist_true = parser.parse(('else', 'endifcurrentview'))
token = parser.next_token()
if token.contents == 'else':
nodelist_false = parser.parse(('endifcurrentview',))
parser.delete_first_token()
else:
nodelist_false = NodeList()
return IfCurrentViewNode(view_name, nodelist_true, nodelist_false)
@register.tag
def ifcurrentview(parser, token):
"""
Outputs the contents of the block if the current view match the argument.
Examples::
{% ifcurrentview 'path.to.some_view' %}
...
{% endifcurrentview %}
{% ifcurrentview 'path.to.some_view' %}
...
{% else %}
...
{% endifcurrentview %}
"""
return do_ifcurrentview(parser, token)
You could calculate whatever you need (request.path = reverse('orders_list') for example) in your view and pass the result to the template. In the view (python code) you can manipulate the path as much as you like.
You can check if one URL is the prefix of the other.
Try this jQuery statement:
$("[href='{{ request.path }}']").parents("li").addClass('active');
Usage: {% url_active "home" "other-view" "and-so-on" success="active-specific-class" %}
from django import template
register = template.Library()
@register.simple_tag(takes_context=True)
def url_active(context, *args, **kwargs):
if 'request' not in context:
return ''
request = context['request']
if request.resolver_match.url_name in args:
return kwargs['success'] if 'success' in kwargs else 'active'
else:
return ''
I figured out a hacked way to do it in jQuery... but I'm still open for a better solution.
jQuery:
var tab_list = {
'orders-tab' : '{% url orders_list %}',
'users-tab' : '{% url users_list %}',
'vendors-tab': '{% url vendors_list %}',
'places-tab' : '{% url places_list %}'
}
$(document).ready(function() {
for(var property in tab_list) {
if('{{ request.path }}' == tab_list[property]) {
$('#' + property).addClass('active-tab')
break
}
}
})
HTML:
<ul id="tabs" class="fl">
<li><a href="#" id="dashboard-tab" class="dashboard-tab">Dashboard</a></li>
<li><a href="{% url orders_list %}" id="orders-tab">Orders</a></li>
<li><a href="{% url users_list %}" id="users-tab">Users</a></li>
<li><a href="{% url vendors_list %}" id="vendors-tab">Vendors</a></li>
<li><a href="{% url places_list %}" id="places-tab">Places</a></li>
</ul>
来源:https://stackoverflow.com/questions/10263482/compare-request-path-with-a-reversed-url-in-django-template