使用Django模板的导航菜单
我在用Django模板做一个简单的导航菜单时,遇到了一个问题,就是没法给某个菜单项设置当前的样式类。下面是我的基础模板:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{% block title %}{% endblock %}</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<link rel="stylesheet" type="text/css" href="/media/css/base.css" />
<link rel="stylesheet" type="text/css" href="/media/css/login.css" />
<link rel="stylesheet" href="/site_media/css/style.css" type="text/css" />
<!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="/media/css/ie.css" /><![endif]-->
</head>
<body class="{% block bodyclass %}{% endblock %}">
{% block content %}{% endblock %}
{% block footer %}{% endblock %}
</body>
</html>
接下来我有一个nav.html文件:
<ul id="top">
<li><a class="{% block home %}{% endblock %}" href="/">Home</a></li>
<li><a class="{% block myaccount %}{% endblock %}" href="/profile/">My Account</a></li>
{% if perms.staffing.add_staffrequest %}
<li><a class="{% block createsr %}{% endblock %}"
href="/create/staffrequest/">Staff Request</a></li>
{% endif %}
</ul>
然后在我的home.html中,我发现没法让当前的样式类'current'显示出来:
{% extends "base.html" %}
{% block title %}Home Portal{% endblock %}
{% block content %}
<div id="content">
{% include "nav.html" %}
{% block home %}current{% endblock %}
<div id="intro">
<p>Hello, {{ user.first_name }}.</p>
<p>Please create a Staff Request here by filling out the form
below.</p>
</div> <!-- end intro -->
<div id="logout">
<a href="/accounts/logout" alt="Sign Off" title="Sign Off">Sign Off</a>
</div>
</div> <!-- end content -->
{% endblock %}
样式类'current'没有在导航中显示出来,这样我就无法根据用户所在的页面来设置视觉效果。
3 个回答
你可以通过使用 DRY 菜单自定义模板标签来解决重复的问题。这个方法还可以解决菜单项的激活和非激活状态的问题。下面是详细说明,源代码可以在这里找到:http://djangosnippets.org/snippets/2722/
DRY 菜单模板标签的介绍。
这是一个自定义模板标签的描述,用于创建 DRY 菜单。它解决了你网站模板中重复标记的问题。菜单中总是有一个激活的选项和一个或多个非激活的选项。
如何使用
在父模板中定义你的菜单结构:
{% defmenu "menu1" %}
{% active %}<span class='active'>{{text}}</span>{% endactive %}
{% inactive %}<a href='{{url}}'>{{text}}</a>{% endinactive %}
{% opt "opt1" "/opt1/" %}Go to opt1{% endopt %}
{% opt "opt2" "/opt2/" %}Go to opt2{% endopt %}
{% opt "opt3" "/opt3/" %}Go to opt3{% endopt %}
{% enddefmenu %}
菜单有它的名字('defmenu' 标签的第一个参数)。
标签 'opt' 的第一个参数是菜单选项的名称。'active'/'inactive' 中的text 将被 'opt' 标签的内部文本(比如“去选项...”)替换,'active'/'inactive' 中的url 将被 'opt' 标签的第二个参数替换。
要在子模板中生成一个带有选中选项的菜单,可以这样做:
{% menu "menu1" "opt1" %}
在这里:“menu1”是通过 'defmenu' 标签定义的菜单名称,“opt1”是被选中的选项。
应用 'menu' 后的结果是:
<span class='active'> Go to opt1</span> <a href='"/opt2/"'>Go to opt2</a> <a href='"/opt3/"'>Go to opt3</a>
另一种处理这个问题的方法是直接在CSS文件中使用body.class...
nav.html
<ul id="top">
<li><a class="home" href="/">Home</a></li>
<li><a class="myaccount" href="/profile/">My Account</a></li>
{% if perms.staffing.add_staffrequest %}
<li><a class="createsr"
href="/create/staffrequest/">Staff Request</a></li>
{% endif %}
</ul>
home.html
{% block bodyclass %}home{% endblock %}
你的CSS文件
body.home li.home { font-weight: bold; color: blue; }
body.myaccount li.myaccount { font-weight: bold; color: blue; }
body.createsr li.createsr { font-weight: bold; color: blue; }
这样做虽然不符合“不要重复自己”的原则,但有时候比搞复杂的模板要简单得多。
我觉得你不能直接替换一个包含的模板里的块。我的建议是,你需要重新考虑一下你的模板逻辑。在我看来,它应该是这样的:
base.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{% block title %}{% endblock %}</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<link rel="stylesheet" type="text/css" href="/media/css/base.css" />
<link rel="stylesheet" type="text/css" href="/media/css/login.css" />
<link rel="stylesheet" href="/site_media/css/style.css" type="text/css" />
<!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="/media/css/ie.css" /><![endif]-->
</head>
<body class="{% block bodyclass %}{% endblock %}">
{% block content %}
<div id="content">
{% block navigation %}
<ul id="top">
<li><a class="{% block home %}{% endblock %}" href="/">Home</a></li>
<li><a class="{% block myaccount %}{% endblock %}" href="/profile/">My Account</a></li>
{% if perms.staffing.add_staffrequest %}
<li><a class="{% block createsr %}{% endblock %}"
href="/create/staffrequest/">Staff Request</a></li>
{% endif %}
</ul>
{% endblock %}
{% block real_content %}
<div id="intro">
<p>Hello, {{ user.first_name }}.</p>
<p>Please create a Staff Request here by filling out the form below.</p>
</div> <!-- end intro -->
<div id="logout">
<a href="/accounts/logout" alt="Sign Off" title="Sign Off">Sign Off</a>
</div>
{% endblock %}
</div> <!-- end content -->
{% endblock %}
{% block footer %}{% endblock %}
</body>
</html>
而你的 home.html 应该像这样:
{% extends "base.html" %}
{% block title %}Home Portal{% endblock %}
{% block home %}current{% endblock %}
{% block real_content %}
<div id="content">
<div id="intro">
<p>Hello, {{ user.first_name }}.</p>
<p>Please create a Staff Request here by filling out the form
below.</p>
</div> <!-- end intro -->
<div id="logout">
<a href="/accounts/logout" alt="Sign Off" title="Sign Off">Sign Off</a>
</div>
</div> <!-- end content -->
{% endblock %}