问题
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!
回答1:
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.
回答2:
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>
回答3:
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 ''
回答4:
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');
回答5:
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)
回答6:
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.
回答7:
Try this jQuery statement:
$("[href='{{ request.path }}']").parents("li").addClass('active');
回答8:
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 ''
回答9:
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