2012-04-21 81 views
4

我知道request.path會給我當前的URL。將request.path與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

由美洲獅的回答啓發:

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

該解決方案是簡單的JS,並適用於引導的導航欄。對於OP的情況下可以使用:

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

大廈Josh的回答,您可以使用「如果」標籤的簡單:

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

不錯!而且不需要自定義模板標籤! – Inti 2016-12-15 10:54:04

2

一個更好的版本最多的回答將是扭轉視圖名:

{% 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

與IF-THEN-ELSE選項:A液

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 – 2017-11-28 14:34:15

+0

我想這是可測試的。不知道如何。你應該看看Django如何測試它的標籤(例如https://github.com/django/django/blob/3c447b108ac70757001171f7a4791f493880bf5b/tests/template_tests/tests.py#L104) – zigarn 2017-11-28 19:50:09