在Django模板中考虑标题菜单

时间:2013-05-17 13:15:53

标签: django navigation django-views django-templates

我正在使用django建立一个网站,每个页面顶部都有一个标题,基本上是一个带有一些链接的菜单,在整个页面中保持不变。

但是,根据您所在的页面,我想通过添加“活动”类来突出显示菜单上的相应链接。为此,我目前正在执行以下操作:每个页面都有一个完整的菜单块,它集成在一般布局中,不包含菜单。例如,page2看起来像这样:

{% extends "layout.html" %}
{% block menu %}
<li><a href="{% url 'myapp:index' %}">Home</a></li>
<li><a href="{% url 'myapp:page1' %}">page1</a></li>
<li class="active"><a href="{% url 'myapp:page2' %}">page2</a></li>
<li><a href="{% url 'myapp:page3' %}">page3</a></li>
{% endblock %}

问题是,除了那个解决方案不那么漂亮之外,每次我想添加一个链接到标题菜单时,我必须修改我拥有的每一个页面。由于这远非最佳,我想知道你们中是否有人会知道更好的方法。

提前致谢!

3 个答案:

答案 0 :(得分:6)

您可以创建自定义模板标签:

from django import template
from django.core.urlresolvers import reverse, NoReverseMatch, resolve

register = template.Library()

@register.simple_tag
def active(request, view_name):
    url = resolve(request.path)
    if url.view_name == view_name:
        return 'active'
    try:
        uri = reverse(view_name)
    except NoReverseMatch:
        uri = view_name
    if request.path.startswith(uri):
        return 'active'
    return ''

并在模板中使用它来识别URL加载的页面

<li class="{% active request 'car_edit' %}"><a href="{% url 'car_edit' car.pk %}">Edit</a></li>

答案 1 :(得分:3)

如果每个视图都有一个“页面”对象,您可以将导航项目的slug与对象的slug进行比较

<强> navigation.html

<ul>
    {% for page in navigation %}
        <li{% ifequal object.slug page.slug %} class="active"{% endifequal %}>
            <a href="{{ page.get_absolute_url }}">{{ page.title }}</a>
        </li>
    {% endfor %}
</ul>

<强> base.html文件

<html>
    <head />
    <body>
        {% include "navigation.html" %}
        {% block content %}
            Welcome Earthling.
        {% endblock %}
    </body>
</html>

<强> page.html中

{% extends "base.html" %}

{% block content %}
    {{ object }}
{% endblock %}

导航可能是包含所有页面的context_processor变量,而object是当前PageDetailView对象变量

<强>声明

如Paulo所述,您的问题有很多解决方案。当然这个解决方案假设每个视图都包含一个页面对象,这个概念通常由CMS实现。如果您的视图不是从Page应用程序派生的,则必须在导航中注入页面伪装者(至少持有get_absolute_urltitle属性)。

这可能是一次非常好的学习体验,但您可能会节省安装feinCMSdjango-cms的加载时间,这两者都定义了ApplicationContent原则。

答案 2 :(得分:1)

您可以使用include标记并将其传递给当前页面的值。

例如,这可能是一个单独的文件,仅用于声明菜单模板:

menu.html

{% if active = "a" %}
<li><a href="{% url 'myapp:index' %}">Home</a></li>
{% if active = "b" %}
<li><a href="{% url 'myapp:page1' %}">page1</a></li>
{% if active = "c" %}
<li class="active"><a href="{% url 'myapp:page2' %}">page2</a></li>
{% if active = "d" %}
<li><a href="{% url 'myapp:page3' %}">page3</a></li>

并在您的模板中调用此内容:

{% include 'path/to/menu.html' with active="b"%} # or a or c or d.

希望它有所帮助!