我想渲染一些结构:
<a href='/home'>Home</a>
<span class='active'>Community</span>
<a href='/about'>About</a>
选择社区菜单项。我有几个模板相同选项的菜单,但我不想为每个模板创建组合:
<!-- for Home template-->
<span class='active'>Home</span>
<a href='/comminuty'>Community</a>
<a href='/about'>About</a>
...
<!-- for Community template-->
<a href='/home'>Home</a>
<span class='active'>Community</span>
<a href='/about'>About</a>
...
<!-- for About template-->
<a href='/home'>Home</a>
<a href='/community'>Community</a>
<span class='active'>About</span>
我们有永久的菜单项列表,因此,它可以是更有效的方式 - 只创建一个菜单的通用结构,然后使用模板的必需选项呈现菜单。
例如,它可能是允许这样做的标记。
答案 0 :(得分:62)
想出另一种方法,这要归功于这个答案:https://stackoverflow.com/a/17614086/34871
给出一个url模式,例如:
url(r'^some-url', "myapp.myview", name='my_view_name'),
my_view_name
可通过request
用于模板(请记住,您需要使用RequestContext - 使用render_to_response时隐式)
然后菜单项可能如下所示:
<li class="{% if request.resolver_match.url_name == "my_view_name" %}active{% endif %}"><a href="{% url "my_view_name" %}">Shortcut1</a></li>
<li class="{% if request.resolver_match.url_name == "my_view_name2" %}active{% endif %}"><a href="{% url "my_view_name2" %}">Shortcut2</a></li>
等
这样,网址可以更改,如果网址参数不同,它仍然可以使用,而且您不需要在其他位置保留菜单项列表。
答案 1 :(得分:48)
您只需使用以下模板标记:
# path/to/templatetags/mytags.py
import re
from django import template
from django.core.urlresolvers import reverse, NoReverseMatch
register = template.Library()
@register.simple_tag(takes_context=True)
def active(context, pattern_or_urlname):
try:
pattern = '^' + reverse(pattern_or_urlname)
except NoReverseMatch:
pattern = pattern_or_urlname
path = context['request'].path
if re.search(pattern, path):
return 'active'
return ''
所以,在你的模板中:
{% load mytags %}
<nav><ul>
<li class="nav-home {% active 'url-name' %}"><a href="#">Home</a></li>
<li class="nav-blog {% active '^/regex/' %}"><a href="#">Blog</a></li>
</ul></nav>
还有另一种方法,仅使用HTML&amp; CSS,您可以在任何框架或静态站点中使用。
考虑到你有一个像这样的导航菜单:
<nav><ul>
<li class="nav-home"><a href="#">Home</a></li>
<li class="nav-blog"><a href="#">Blog</a></li>
<li class="nav-contact"><a href="#">Contact</a></li>
</ul></nav>
创建一些基本模板,每个模板用于您网站的每个会话,例如:
home.html
base_blog.html
base_contact.html
所有这些模板都使用块“部分”扩展base.html
,例如:
...
<body id="{% block section %}section-generic{% endblock %}">
...
然后,以base_blog.html
为例,您必须具备以下条件:
{% extends "base.html" %}
{% block section %}section-blog{% endblock %}
现在只使用CSS定义活动菜单项很容易:
#section-home .nav-home,
#section-blog .nav-blog,
#section-contact .nav-contact { background-color: #ccc; }
答案 2 :(得分:29)
我找到了简单而优雅的DRY解决方案。
这是片段: http://djangosnippets.org/snippets/2421/
**Placed in templates/includes/tabs.html**
<ul class="tab-menu">
<li class="{% if active_tab == 'tab1' %} active{% endif %}"><a href="#">Tab 1</a></li>
<li class="{% if active_tab == 'tab2' %} active{% endif %}"><a href="#">Tab 2</a></li>
<li class="{% if active_tab == 'tab3' %} active{% endif %}"><a href="#">Tab 3</a></li>
</ul>
**Placed in your page template**
{% include "includes/tabs.html" with active_tab='tab1' %}
答案 3 :(得分:4)
您可以使用名称,URL以及它是否为活动项来创建上下文变量links
:
{% for name, url, active in links %}
{% if active %}
<span class='active'>{{ name }}</span>
{% else %}
<a href='{{ url }}'>{{ name }}</a>
{% endif %}
{% endfor %}
如果所有页面上都有此菜单,您可以使用上下文处理器:
def menu_links(request):
links = []
# write code here to construct links
return { 'links': links }
然后,在您的设置文件中,将该功能添加到TEMPLATE_CONTEXT_PROCESSORS
,如下所示:path.to.where.that.function.is.located.menu_links
。这意味着将为每个模板调用函数menu_links
,这意味着变量links
在每个模板中都可用。
答案 4 :(得分:1)
假设导航项是与当前页面具有相同URL的链接,则可以使用JavaScript。这是一个带注释的方法,用于在class="active"
的导航菜单中将li
添加到class="nav"
:
// Get the path name (the part directly after the URL) and append a trailing slash
// For example, 'http://www.example.com/subpage1/sub-subpage/'
// would become '/subpage1/'
var pathName = '/' + window.location.pathname.split('/')[1];
if ( pathName != '/' ) { pathName = pathName + '/'; }
// Form the rest of the URL, so that we now have 'http://www.example.com/subpage1/'
// This returns a top-level nav item
var url = window.location.protocol + '//' +
window.location.host +
pathName;
console.log(url);
// Add an 'active' class to the navigation list item that contains this url
var $links = document.querySelectorAll('.nav a');
$link = Array.prototype.filter.call( $links, function(el) {
return el.href === url;
})[0];
$link.parentNode.className += ' active';
此方法意味着您只需将其弹出到基本模板中一次就可以忘掉它。没有重复,也没有在每个模板中手动指定页面URL。
一个警告:这显然只有在找到的url
与导航链接href
匹配时才有效。另外可以在JS中指定几个特殊用例,或根据需要定位不同的父元素。
这是一个可运行的示例(请记住,在StackSnippets上运行代码段):
// Get the path name (the part directly after the URL) and append a trailing slash
// For example, 'http://www.example.com/subpage1/sub-subpage/'
// would become '/subpage1/'
var pathName = '/' + window.location.pathname.split('/')[1];
if ( pathName != '/' ) { pathName = pathName + '/'; }
// Form the rest of the URL, so that we now have 'http://www.example.com/subpage1/'
// This returns a top-level nav item
var url = window.location.protocol + '//' +
window.location.host +
pathName;
console.log(url);
// Add an 'active' class to the navigation list item that contains this url
var $links = document.querySelectorAll('.nav a');
$link = Array.prototype.filter.call( $links, function(el) {
return el.href === url;
})[0];
$link.parentNode.className += ' active';
li {
display: inline-block;
margin: 0 10px;
}
a {
color: black;
text-decoration: none;
}
.active a {
color: red;
}
<ul class="nav">
<li>
<a href="http://example.com/">Example Link</a>
</li>
<li>
<a href="http://stacksnippets.net/js/">This Snippet</a>
</li>
<li>
<a href="https://google.com/">Google</a>
</li>
<li>
<a href="http://stackoverflow.com/">StackOverflow</a>
</li>
</ul>
答案 5 :(得分:1)
这是我的解决方法:
{% url 'module:list' as list_url %}
{% url 'module:create' as create_url %}
<ul>
<li><a href="{% url 'module:list' %}" class="{% if request.path == list_url %}active{% endif %}">List Page</a></li>
<li><a href="{% url 'module:create' %}" class="{% if request.path == create_url %}active{% endif %}">Creation Page</a></li>
</ul>
答案 6 :(得分:0)
根据@ vincent的回答,有一种更简单的方法可以做到这一点,而不会搞乱django url模式。
可以根据渲染的菜单项路径检查当前请求路径,如果它们匹配,那么这是活动项。
在下面的示例中,我使用django-mptt渲染菜单,但可以用每个菜单项路径替换node.path
。
<li class="{% if node.path == request.path %}active{% endif %}">
<a href="node.path">node.title</a>
</li>
答案 7 :(得分:0)
我今天遇到了如何动态激活&#34;类别&#34;在侧边栏中。这些类别有来自DB的slu。
我通过检查类别slug是否在当前路径中来解决它。 slu is是独一无二的(标准做法)所以我认为这应该没有任何冲突。
{% if category.slug in request.path %}active{% endif %}
获取类别并激活当前类别的循环的完整示例代码。
{% for category in categories %}
<a class="list-group-item {% if category.slug in request.path %}active{% endif %}" href="{% url 'help:category_index' category.slug %}">
<span class="badge">{{ category.article_set.count }}</span>
{{ category.title }}
</a>
{% endfor %}
答案 8 :(得分:0)
我正在使用更简单纯粹的CSS解决方案。它有其局限性,我知道并可以使用它,但它避免了笨拙的CSS类选择器,如下所示:
<a href="index.html" class="item{% if url == request.path %}active{% endif %}">index</a>
由于缺少active
之前的空格字符,因此类选择器会被调用itemactive
而不是item active
,而这并不是那么容易出错。
对我来说,这个纯CSS解决方案效果更好:
a.item /* all menu items are of this class */
{
color: black;
text-decoration: none;
}
a.item[href~="{{ request.path }}"] /* just the one which is selected matches */
{
color: red;
text-decoration: underline;
}
注意:如果URL有其他路径组件,这甚至有效,因为href
也部分匹配。这可能最终导致与多个匹配的“冲突”,但通常它只是起作用,因为在结构良好的网站上,URL的“子目录”通常是所选菜单项的子目录。
答案 9 :(得分:0)
我想出了一种方法,在包含菜单的父模板中使用块标签来实现这样的效果。
base.html
- 父模板:
<a href="/" class="{% block menu_home_class %}{% endblock %}">Home</a>
<a href="/about" class="{% block menu_about_class %}{% endblock %}">About</a>
<a href="/contact" class="{% block menu_contact_class %}{% endblock %}">Contact</a>
{% block content %}{% endblock %}
about.html
- 特定网页的模板:
{% extends "base.html" %}
{% block menu_about_class %}active{% endblock %}
{% block content %}
About page content...
{% endblock %}
如您所见,不同页面模板之间的差异是包含active
的块的名称。 contact.html
会使用menu_contact_class
,依此类推。
这种方法的一个好处是,您可以拥有多个具有相同活动菜单项的子页面。例如,about页面可能有子页面,提供有关公司每个团队成员的信息。对于每个子页面,“关于”菜单项保持活动状态是有意义的。
答案 10 :(得分:0)
我个人认为最简单的方法是为每个链接创建块,如下所示:
# base.py
...
<a href="{% url 'home:index' %}" class={% block tab1_active %}{% endblock %}>
...
<a href="{% url 'home:form' %}" class={% block tab2_active %}{% endblock %}>
...
然后在每个相对模板中将该链接声明为“活动”,例如:
tab1模板:
{% block tab1_active %}"active"{% endblock %}
tab2模板:
{% block tab2_active %}"active"{% endblock %}