django导航
我刚刚在django做了我的第一个小webapp,我喜欢它。我即将开始将一个旧的PHP生产站点转换为django,作为其模板的一部分,有一个导航栏 在PHP中,我在模板代码中对照当前URL检查每个nav选项的URL,如果它们对齐,则应用CSS类。这里乱七八糟 django是否有更好的方法或处理模板中代码的好方法django导航,django,navigation,Django,Navigation,我刚刚在django做了我的第一个小webapp,我喜欢它。我即将开始将一个旧的PHP生产站点转换为django,作为其模板的一部分,有一个导航栏 在PHP中,我在模板代码中对照当前URL检查每个nav选项的URL,如果它们对齐,则应用CSS类。这里乱七八糟 django是否有更好的方法或处理模板中代码的好方法 首先,如何获取当前URL?您可以使用带有适当参数的来获取当前URL。您可以将类或id应用于页面的主体元素,而不是特定的导航项 HTML: 我使用模板继承来定制导航。例如: base.ht
首先,如何获取当前URL?您可以使用带有适当参数的来获取当前URL。您可以将类或id应用于页面的主体元素,而不是特定的导航项 HTML:
我使用模板继承来定制导航。例如: base.html
<html>
<head>...</head>
<body>
...
{% block nav %}
<ul id="nav">
<li>{% block nav-home %}<a href="{% url 'home' %}">Home</a>{% endblock %}</li>
<li>{% block nav-about %}<a href="{% url 'about' %}">About</a>{% endblock %}</li>
<li>{% block nav-contact %}<a href="{% url 'contact' %}">Contact</a>{% endblock %}</li>
</ul>
{% endblock %}
...
</body>
</html>
{% load tags %}
{% url 'home_url_name' as home %}
{% url 'services_url_name' as services %}
{% url 'contact_url_name' as contact %}
<div id="navigation">
<a class="{% active request home %}" href="{{ home }}">Home</a>
<a class="{% active request services %}" href="{{ services }}">Services</a>
<a class="{% active request contact %}" href="{{ contact }}">Contact</a>
</div>
...
...
{%block nav%}
{%endblock%}
...
关于.html
{% extends "base.html" %}
{% block nav-about %}<strong class="nav-active">About</strong>{% endblock %}
{%extends“base.html”%}
{%block nav about%}about{%endblock%}
谢谢你们的回答,先生们。我又开始追求一些稍微不同的东西
在我的模板中:
<li{{ link1_active }}>...link...</li>
<li{{ link2_active }}>...link...</li>
<li{{ link3_active }}>...link...</li>
<li{{ link4_active }}>...link...</li>
<ul>
{% for category in category_list %}
<li class="tab{% ifequal active_category category %}-active{% endifequal %}">
<a href="{{ category.get_absolute_url }}">{{ category.cat }}</a>
</li>
{% endfor %}
</ul>
<body id="section-{% block section %}home{% endblock %}">
{% include "includes/navigation.html" with items=navi %}
<a href="/dashboard/" {% if 'dashboard' in view.breadcrumbs %}class="active"{% endif %}>Dashboard</a>
<a href="/list/" {% if 'list' in view.breadcrumbs %}class="active"{% endif %}>List</a>
<a href="/detail/" {% if 'detail' in view.breadcrumbs %}class="active"{% endif %}>Detail</a>
<ul>
<li{{active_nav_menu.node_explorer }}><a href="{% url 'node_explorer' '' %}">Explore</a></li>
<li{{active_nav_menu.node_create }}><a href="{% url 'node_create' path %}">Create</a></li>
<li{{active_nav_menu.node_edit }}><a href="{% url 'node_edit' path %}">Edit</a></li>
<li{{active_nav_menu.node_delete }}><a href="{% url 'node_delete' path %}">Delete</a></li>
</ul>
这会使模板的可读性降低一些,但我同意,最好不要从URL文件推送原始HTML。我这样做:
<a class="tab {% ifequal active_tab "statistics" %}active{% endifequal %}" href="{% url Member.Statistics %}">Statistics</a>
from django import template
register = template.Library()
@register.tag
def active(parser, token):
args = token.split_contents()
template_tag = args[0]
if len(args) < 2:
raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
return NavSelectedNode(args[1:])
class NavSelectedNode(template.Node):
def __init__(self, urls):
self.urls = urls
def render(self, context):
path = context['request'].path
for url in self.urls:
if '"' not in url:
cpath = template.Variable(url).resolve(context)
else:
cpath = url.strip('"')
if (cpath == '/' or cpath == '') and not (path == '/' or path == ''):
return ""
if path.startswith(cpath):
return 'active'
return ""
{% load lineage %}
<div id="navigation">
<a class="{% ancestor '/home/' %}" href="/home/">Home</a>
<a class="{% ancestor '/services/' %}" href="/services/">Services</a>
<a class="{% ancestor '/contact/' %}" href="/contact/">Contact</a>
</div>
在你看来:
from django.template import RequestContext
def my_view(request):
# do something awesome here
return template.render(RequestContext(request, context_dict))
您不需要if来执行此操作,请查看以下代码: tags.py
@register.simple_tag
def active(request, pattern):
import re
if re.search(pattern, request.path):
return 'active'
return ''
url.py
urlpatterns += patterns('',
(r'/$', view_home_method, 'home_url_name'),
(r'/services/$', view_services_method, 'services_url_name'),
(r'/contact/$', view_contact_method, 'contact_url_name'),
)
base.html
<html>
<head>...</head>
<body>
...
{% block nav %}
<ul id="nav">
<li>{% block nav-home %}<a href="{% url 'home' %}">Home</a>{% endblock %}</li>
<li>{% block nav-about %}<a href="{% url 'about' %}">About</a>{% endblock %}</li>
<li>{% block nav-contact %}<a href="{% url 'contact' %}">Contact</a>{% endblock %}</li>
</ul>
{% endblock %}
...
</body>
</html>
{% load tags %}
{% url 'home_url_name' as home %}
{% url 'services_url_name' as services %}
{% url 'contact_url_name' as contact %}
<div id="navigation">
<a class="{% active request home %}" href="{{ home }}">Home</a>
<a class="{% active request services %}" href="{{ services }}">Services</a>
<a class="{% active request contact %}" href="{{ contact }}">Contact</a>
</div>
{%load tags%}
{%url'home\u url\u name'作为home%}
{%url'服务\u url\u名称'作为服务%}
{%url'联系人\ url\姓名'作为联系人%}
就这样。
有关实施细节,请参阅:我喜欢上面110j的清洁度,所以我取了大部分并进行了重构,以解决它的3个问题:
register=template.Library()
@register.tag
def活动(解析器、令牌):
args=token.split_contents()
模板\标记=args[0]
如果len(args)<2:
raise template.TEMPLATESYNTEXERROR,“%r标记需要至少一个参数”%template\u标记
返回NavSelectedNode(参数[1:])
类NavSelectedNode(template.Node):
定义初始化(自,模式):
self.patterns=模式
def呈现(自身、上下文):
路径=上下文['request']。路径
对于self.patterns中的p:
pValue=template.Variable(p.resolve)(上下文)
如果路径==pValue:
返回“活动”#如果其他引导版本(与3.2兼容)需要,请更改此选项
返回“”
URL.py:
urlpatterns+=模式(“”,
url(r'/$,视图\主页\方法,{},name='home\ url \ name'),
url(r'/services/$',view_services_method,{},name='services_url_name'),
url(r'/contact/$',查看\u contact\u方法,{},name='contact\u url\u name'),
url(r'/contact/$',查看\u contact2\u方法,{},name='contact2\u url\u name'),
)
base.html:
{%load tags%}
{%url home\u url\u name作为home%}
{%url服务\u url\u名称为服务%}
{%url联系人\u url\u姓名作为联系人%}
{%url联系人2\u url\u姓名为联系人2%}
我在同一页上有多个菜单,它们是通过循环动态创建的。上面与上下文相关的帖子给了我一个快速解决方案。希望这对别人有帮助。(除了活动模板标记之外,我还使用了这个选项-我的补丁解决了动态问题)。这似乎是一个愚蠢的比较,但它是有效的。我选择将变量命名为active\u something-unique和somethine-unique,这样它可以与嵌套菜单一起工作
以下是部分视图(足以理解我在做什么):
这是来自模板:
<li{{ link1_active }}>...link...</li>
<li{{ link2_active }}>...link...</li>
<li{{ link3_active }}>...link...</li>
<li{{ link4_active }}>...link...</li>
<ul>
{% for category in category_list %}
<li class="tab{% ifequal active_category category %}-active{% endifequal %}">
<a href="{{ category.get_absolute_url }}">{{ category.cat }}</a>
</li>
{% endfor %}
</ul>
<body id="section-{% block section %}home{% endblock %}">
{% include "includes/navigation.html" with items=navi %}
<a href="/dashboard/" {% if 'dashboard' in view.breadcrumbs %}class="active"{% endif %}>Dashboard</a>
<a href="/list/" {% if 'list' in view.breadcrumbs %}class="active"{% endif %}>List</a>
<a href="/detail/" {% if 'detail' in view.breadcrumbs %}class="active"{% endif %}>Detail</a>
<ul>
<li{{active_nav_menu.node_explorer }}><a href="{% url 'node_explorer' '' %}">Explore</a></li>
<li{{active_nav_menu.node_create }}><a href="{% url 'node_create' path %}">Create</a></li>
<li{{active_nav_menu.node_edit }}><a href="{% url 'node_edit' path %}">Edit</a></li>
<li{{active_nav_menu.node_delete }}><a href="{% url 'node_delete' path %}">Delete</a></li>
</ul>
{类别列表%中的类别的百分比}
-
{%endfor%}
我的解决方案是编写一个简单的上下文处理器,根据请求路径设置变量:
def navigation(request):
"""
Custom context processor to set the navigation menu pointer.
"""
nav_pointer = ''
if request.path == '/':
nav_pointer = 'main'
elif request.path.startswith('/services/'):
nav_pointer = 'services'
elif request.path.startswith('/other_stuff/'):
nav_pointer = 'other_stuff'
return {'nav_pointer': nav_pointer}
(别忘了将自定义处理器添加到settings.py中的TEMPLATE_CONTEXT_PROCESSORS中。)
然后在基本模板中,我对每个链接使用ifequal标记来确定是否附加“active”类。尽管这种方法严格限制了路径结构的灵活性,但它适用于我相对温和的部署。我只想将我的小改进分享给nivhab的帖子。在我的应用程序中,我有子导航,我不想只使用CSS隐藏它们,所以我需要某种“if”标记来显示某个项目的子导航
from django import template
register = template.Library()
@register.tag
def ifnaviactive(parser, token):
nodelist = parser.parse(('endifnaviactive',))
parser.delete_first_token()
import re
args = token.split_contents()
template_tag = args[0]
if len(args) < 2:
raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
return NavSelectedNode(args[1:], nodelist)
class NavSelectedNode(template.Node):
def __init__(self, patterns, nodelist):
self.patterns = patterns
self.nodelist = nodelist
def render(self, context):
path = context['request'].path
for p in self.patterns:
pValue = template.Variable(p).resolve(context)
if path == pValue:
return self.nodelist.render(context)
return ""
来自django导入模板的
register=template.Library()
@register.tag
def ifnaviactive(解析器、令牌):
nodelist=parser.parse(('endifnaviactive',))
parser.delete_first_token()
进口稀土
args=token.split_contents()
模板\标记=args[0]
如果len(args)<2:
raise template.TEMPLATESYNTEXERROR,“%r标记需要至少一个参数”%template\u标记
返回NavSelectedNode(参数[1:],节点列表)
类NavSelectedNode(template.Node):
定义初始化(自我、模式、节点列表):
self.patterns=模式
self.nodelist=节点列表
def呈现(自身、上下文):
路径=上下文['request']。路径
对于self.patterns中的p:
pValue=template.Variable(p.resolve)(上下文)
如果路径==pValue:
返回self.nodelist.render(上下文)
返回“”
您可以使用与活动标记基本相同的方法:
{% url product_url as product %}
{% ifnaviactive request product %}
<ul class="subnavi">
<li>Subnavi item for product 1</li>
...
</ul>
{% endifnaviactive %}
{%url产品\u ur
from django import template
from django.core.urlresolvers import reverse
register = template.Library()
@register.tag
def active(parser, token):
args = token.split_contents()
template_tag = args[0]
if len(args) < 2:
raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
return NavSelectedNode(args[1:])
class NavSelectedNode(template.Node):
def __init__(self, name):
self.name = name
def render(self, context):
if context['request'].path == reverse(self.name[1]):
return 'active'
else:
return ''
url(r'^tasks/my', my_tasks, name = 'my_tasks' ),
<li class="{% active request all_tasks %}"><a href="{% url all_tasks %}">Everyone</a></li>
{% load url from future %}
{% url view as view_url %}
<li class="nav-item{% ifequal view_url request.path %} current{% endifequal %}">
<a href="{{ view_url }}">{{ title }}</a>
</li>
<ul>
{% include "intranet/nav_item.html" with view='intranet.views.home' title='Home' %}
{% include "intranet/nav_item.html" with view='crm.views.clients' title='Clients' %}
</ul>
from django.conf import global_settings
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
'django.core.context_processors.request',
)
<script type="text/javascript" src="/static/js/jquery.js"></script>
<script>
$(document).ready(function(){
var path = location.pathname;
$('ul.navbar a.nav[href$="' + path + '"]').addClass("active");
});
</script>
{% load lineage %}
<div id="navigation">
<a class="{% ancestor '/home/' %}" href="/home/">Home</a>
<a class="{% ancestor '/services/' %}" href="/services/">Services</a>
<a class="{% ancestor '/contact/' %}" href="/contact/">Contact</a>
</div>
class YourDetailView(DetailView):
breadcrumbs = ['detail']
(...)
<a href="/detail/" {% if 'detail' in view.breadcrumbs %}class="active"{% endif %}>Detail</a>
class YourDetailView(DetailView):
breadcrumbs = ['dashboard', 'list', 'detail']
(...)
<a href="/dashboard/" {% if 'dashboard' in view.breadcrumbs %}class="active"{% endif %}>Dashboard</a>
<a href="/list/" {% if 'list' in view.breadcrumbs %}class="active"{% endif %}>List</a>
<a href="/detail/" {% if 'detail' in view.breadcrumbs %}class="active"{% endif %}>Detail</a>
{% url 'some_urlpattern_name' as url %}
<a href="{{url}}"{% if request.path == url %} class="active"{% endif %}>Link</a>
{% load navigation %}
<li{% if request|active:"home" %} class="active"{% endif %}><a href="{% url "home" %}">Home</a></li>
@register.filter(name="active")
def active(request, url_name):
return resolve(request.path_info).url_name == url_name
TEMPLATE_CONTEXT_PROCESSORS = (
...
'django.core.context_processors.request',
)
// DOM Ready
$(function() {
// Highlight current page in nav bar
$('.nav, .navbar-nav li').each(function() {
// Count the number of links to the current page in the <li>
var matched_links = $(this).find('a[href]').filter(function() {
return $(this).attr('href') == window.location.pathname;
}).length;
// If there's at least one, mark the <li> as active
if (matched_links)
$(this).addClass('active');
});
});
var matched_links = $(this).find('a[href]').filter(function() {
var matched = $(this).attr('href') == window.location.pathname;
if (matched)
$(this).click(function() { return false; });
return matched;
}).length;
<ul>
<li{{active_nav_menu.node_explorer }}><a href="{% url 'node_explorer' '' %}">Explore</a></li>
<li{{active_nav_menu.node_create }}><a href="{% url 'node_create' path %}">Create</a></li>
<li{{active_nav_menu.node_edit }}><a href="{% url 'node_edit' path %}">Edit</a></li>
<li{{active_nav_menu.node_delete }}><a href="{% url 'node_delete' path %}">Delete</a></li>
</ul>
<div class="pure-u-1 pure-menu pure-menu-open pure-menu-horizontal header" >
<ul class="">
<li id="home"><a href="{% url 'article:index' %}">Home</a></li>
<li id="news"><a href="{% url 'article:index' %}">News</a></li>
<li id="analysis"><a href="{% url 'article:index' %}">Analysis</a></li>
<li id="opinion"><a href="{% url 'article:index' %}">Opinion</a></li>
<li id="data"><a href="{% url 'article:index' %}">Data</a></li>
<li id="events"><a href="{% url 'article:index' %}">Events</a></li>
<li id="forum"><a href="{% url 'article:index' %}">Forum</a></li>
<li id="subscribe"><a href="{% url 'article:index' %}">Subscribe</a></li>
</ul>
<script type="text/javascript">
(function(){
loc=/\w+/.exec(window.location.pathname)[0];
el=document.getElementById(loc).className='pure-menu-selected';
})();
</script>
</div>
# navigation.py
from django import template
from django.core.urlresolvers import resolve
register = template.Library()
@register.filter(name="activate_if_active", is_safe=True)
def activate_if_active(request, urlname):
if resolve(request.get_full_path()).url_name == urlname:
return "active"
return ''
{% load navigation %}
<li class="{{ request|activate_if_active:'url_name' }}">
<a href="{% url 'url_name' %}">My View</a>
</li>
## views.py
def ping(request):
context={}
context["nav_ping"] = "active"
return render(request, 'myapp/ping.html',context)
**Placed in templates as base.html**
{% block tab_menu %}
<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>
{% endblock tab_menu %}
**Placed in your page template**
{% extends "base.html" %}
{% block tab_menu %}
{% with active_tab="tab1" %} {{ block.super }} {% endwith %}
{% endblock tab_menu %}
<li class="nav-item">
<a class="nav-link {% if is_active %}active{% endif %}" href="{% url url_name %}">{{ link_name }}</a>
</li>
from django import template
register = template.Library()
@register.inclusion_tag('fnf/nav_item.html', takes_context=True)
def nav_item(context, url_name, link_name=None):
return {
'url_name': url_name,
'link_name': link_name or url_name.title(),
'is_active': context.request.resolver_match.url_name == url_name,
}
{% load nav %}
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<ul class="navbar-nav mr-auto">
{% nav_item 'dashboard' %}
</ul>
<ul class="nav navbar-nav">
<li>
<a href="{% url 'index' %}">Cities</a>
</li>
<li>
<a href="{% url 'all_cafes' %}">Cafes</a>
</li>
</ul>