Django:找出已选择的菜单中的哪个项目

时间:2009-09-15 17:41:27

标签: django menu

我确定我之前在Stack Overflow上看过这个问题,但是我的生活中找不到它,所以这里什么都没有。

我有一个普通的Django菜单,它使用{% url %}标签和菜单项的静态名称。现在我希望为已选择的菜单项设置不同的样式。但是菜单是在基本模板中呈现的,所以我该如何确定它是哪个菜单项?

4 个答案:

答案 0 :(得分:6)

你肯定可以使用一些丑陋的模板代码来做到这一点,但更全面的方法是使用CSS选择器。这使CSS可以自动为您完成所有工作。

以下是它的工作原理:

根据您所在的页面,您只需在身体中放置一个身份证。 然后在css中你做这样的事情:

#section-aboutme #nav-aboutme,
#section-contact #nav-contact
/* ... put one of these per body/menu item ... */
{
    font-color: red;
}

您在每个菜单项上放置了nav-aboutme和nav-contact id。

CSS将自动选择样式,具体取决于它们所在的身份ID。

答案 1 :(得分:2)

我通常按照Brian建议的方式进行,但是为了适应设计师给我的模板,我使用了更常见的class="selected"方法,我写了{% nav %} template tag

您的HTML导航模板类似于:

{% block nav %}
<ul class="nav">
    <li{% if nav.home %} class="selected"{% endif %}><a href="/">Home</a></li>
    <li{% if nav.about %} class="selected"{% endif %}><a href="/about/">About</a></li>
</ul>
{% endblock %}

要在子模板中设置导航,请执行以下操作:

{% include "base.html" %}
{% load nav %}

{% block nav %}
{% nav "about" %}
{{ block.super }}
{% endblock %}

答案 2 :(得分:2)

您用于生成导航项的自定义标记怎么样?

以下内容采用应为其生成导航项的网址名称及其应显示的文本。如果指定的网址路径与当前网址相同(在'django.core.context_processors.request'中需要TEMPLATE_CONTEXT_PROCESSORS),则会生成一个类别为“已选择”的li标记。在li中,它会生成一个标记,其中包含url_name指定的网址路径。它具有contents指定的内容。

显然,可以根据需要对其进行调整,以便为导航项生成不同的标记。

其余的可以使用CSS完成。

优点:

  • 易于使用

  • 所需的代码很少

  • DRY

  • 可以变得更加灵活

缺点:

  • 需要'django.core.context_processors.request'

  • 要求将网址命名为例如urlpatterns = patterns('django.views.generic.simple', ... (r'^$', 'direct_to_template', {'template': 'index.html'}, 'index'), ... )。这可能会以不同的方式完成(例如传入网址)。

  • 不处理与指定页面不完全相同的页面,因此在url heirarchy中较低的页面上不会将所选类应用于li。例如,如果我在/ products /上,它将突出显示指向/ products /的导航项。如果我在/ products / myProduct /上,则不会突出显示/ products /链接。这可以编码,但它会迫使人们使用合理的网址。例如,将additionalAttrs作业更改为additionalAttrs = ' class=selected' if (context['request'].path.startswith(path) and path != '/') or (context['request'].path == path) else ''

代码:

from django import template
from django.core.urlresolvers import reverse

register = template.Library()

class NavNode(template.Node):
    def __init__(self, url_name, contents):
        self.url_name = url_name
        self.contents = contents

    def render(self, context):
        path = reverse(self.url_name)
        additionalAttrs = ' class=selected' if path == context['request'].path else ''
        return '<li'+additionalAttrs+'><a href="'+path+'">'+self.contents+'</a></li>'

@register.tag
def nav_link(parser, token):
    bits = token.split_contents()
    if len(bits) == 3:
        contents = bits.pop()
        url_name = bits.pop()
    else:
        raise template.TemplateSyntaxError, "%r tag requires a single argument" % bits[0]

    if contents[0] == contents[-1] and contents[0] in ('"', "'"):
        contents = contents[1:-1]

    return NavNode(url_name, contents)                

答案 3 :(得分:1)

您可以将request.path传递给模板

from django.shortcuts import render_to_response
from django.template import RequestContext
return render_to_response('templ.html', {'page':request.path}, context_instance=RequestContext(request))

然后使用丑陋的if模板标签将CSS类添加到菜单项