2012-04-21 2 views
4

Я понимаю, что request.path предоставит мне текущий URL-адрес.Сравнить request.path с обратным URL-адресом в шаблоне Django

В настоящее время я работаю над base.html шаблона с закладками CSS, и я хочу, чтобы шаблон, чтобы узнать, какая вкладка в настоящее время «активный» и передать class="active-tab" к <a> тега.

Так что я хотел сделать что-то вроде

<a href="{% url orders_list %}" 
    {% if request.path = reverse('orders_list') %} 
     class="active-tab" 
    {$ endif %} 
>Orders</a> 

Но я уверен, что вы не можете сделать это if сравнения. Я также хочу, чтобы базовый (?) URL-адрес игнорировал любые параметры GET.

Любые предложения или советы также приветствуются. Заранее спасибо!

ответ

3

Вы можете использовать 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 '' 

Тогда использование является своего рода, как это в шаблоне:

{% load my_tags %} 

{% url orders_list as orders %} 
<li class="{% active request orders %}"> 
    <a href="{{ orders }}"> Orders </a> 
</li> 

Вы можете изменить шаблон, как пожелаете.

1

Вы можете вычислить все, что вам нужно (request.path = reverse('orders_list')), на ваш взгляд и передать результат в шаблон. В представлении (код Python) вы можете манипулировать путем столько, сколько хотите.

Вы можете проверить, является ли один URL префикс другого.

0

Я вычислил взломанный способ сделать это в jQuery ... но я все еще открыт для лучшего решения.

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> 
1

Попробуйте это заявление JQuery:

$("[href='{{ request.path }}']").parents("li").addClass('active'); 
2

Вдохновленный ответ Cougar в:

$("ul.nav [href='"+window.location.pathname+"']").parents("li").addClass('active'); 

Это решение равнину JS, и работает для панели навигации Bootstrap в. Для сценария Ора в один можно использовать:

$("[href='"+window.location.pathname+"']").addClass('active-tab'); 
10

Опираясь на ответ Джоша, вы можете использовать простой «если» тег:

{% url 'orders_list' as orders_list_url %} 
<a{% if request.path == orders_list_url %} class="active"{% endif %} 
    href="{{ orders_list_url }}">Orders</a> 
+0

Nice! И нет необходимости в настраиваемом теге шаблона! – Inti

2

Лучший вариантом верхнего ответа будет обратным VIEWNAME :

{% url_active 'reverse_viewname' %} 

Эта версия не требует, чтобы пройти в request. Вместо этого мы указываем, что тегу нужен контекст, а затем получить запрос от этого.

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 '' 
1

Использование: {% 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 '' 
2

Раствор с, если-то-еще вариант:

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) 
+0

Ур код отлично работает. Есть ли способ написать для этого простой тест? Я хочу сохранить процентную долю в тестировании. Написал вопрос SO именно для этого запроса: https://stackoverflow.com/questions/47534145/how-to-write-a-test-case-for-this-django-custom-tag –

+0

Я думаю, это можно проверить. Не знаю, как это сделать. Вы должны посмотреть, как Django проверяет свои теги (например, https://github.com/django/django/blob/3c447b108ac70757001171f7a4791f493880bf5b/tests/template_tests/tests.py#L104) – zigarn

Смежные вопросы