我刚刚在django完成了我的第一个小webapp,我喜欢它.我即将开始将旧的生产PHP站点转换为django,作为其模板的一部分,还有一个导航栏.
在PHP中,我在模板代码中检查每个导航选项的URL与当前URL,如果它们对齐,则应用CSS类.这太可怕了.
是否有更好的django或处理模板中的代码的好方法?
首先,我将如何获取当前的URL?
您不需要if,请查看以下代码:
tags.py
@register.simple_tag def active(request, pattern): import re if re.search(pattern, request.path): return 'active' return ''
urls.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文件
{% load tags %} {% url 'home_url_name' as home %} {% url 'services_url_name' as services %} {% url 'contact_url_name' as contact %}
而已.有关实现的详细信息,请查看:
gnuvince.wordpress.com
110j.wordpress.com
我使用模板继承来自定义导航.例如:
base.html文件
... ... {% block nav %}
about.html
{% extends "base.html" %} {% block nav-about %}About{% endblock %}
我喜欢上面的110j的清洁度,所以我把它的大部分用于解决我遇到的3个问题并进行了重构:
正则表达式将"主页"网址与其他所有网址相匹配
我需要多个URL映射到一个导航选项卡,所以我需要一个更复杂的标签,它需要不同数量的参数
修复了一些网址问题
这里是:
tags.py:
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, patterns):
self.patterns = patterns
def render(self, context):
path = context['request'].path
for p in self.patterns:
pValue = template.Variable(p).resolve(context)
if path == pValue:
return "active" # change this if needed for other bootstrap version (compatible with 3.2)
return ""
urls.py:
urlpatterns += patterns('',
url(r'/$', view_home_method, {}, name='home_url_name'),
url(r'/services/$', view_services_method, {}, name='services_url_name'),
url(r'/contact/$', view_contact_method, {}, name='contact_url_name'),
url(r'/contact/$', view_contact2_method, {}, name='contact2_url_name'),
)
base.html文件:
{% load tags %}
{% url home_url_name as home %}
{% url services_url_name as services %}
{% url contact_url_name as contact %}
{% url contact2_url_name as contact2 %}
我是django-lineage的作者,我是专门为解决这个问题写的:D
我在自己的项目中使用(完全可以接受的)jpwatts方法变得恼火,并从110j的答案中汲取灵感.天堂看起来像这样:
{% load lineage %}
ancestor
如果参数与当前页面URL的开头匹配,则简单地将其替换为"active".
{% url %}
还支持变量参数和完整类型反向分辨率.我在一些配置选项中添加了一些选项,并将其打包并打包以供所有人使用.
如果有人有兴趣,请阅读以下内容:
>> github.com/marcuswhybrow/django-lineage自Django 1.5开始:
在所有基于类的通用视图(或从ContextMixin继承的任何基于类的视图)中,上下文字典包含指向View实例的视图变量.
因此,如果您使用此类视图,则可以添加类似于breadcrumbs
类级别字段的内容并在模板中使用它.
示例视图代码:
class YourDetailView(DetailView): breadcrumbs = ['detail'] (...)
在您的模板中,您可以通过以下方式使用它:
Detail
如果要另外"突出显示"父导航项,则需要扩展breadcrumbs
列表:
class YourDetailView(DetailView): breadcrumbs = ['dashboard', 'list', 'detail'] (...)
...并在您的模板中:
Dashboard List Detail
这是简单而干净的解决方案,适用于嵌套导航.
您可以将类或id应用于页面的body元素,而不是应用于特定的nav项.
HTML:
CSS:
body.home #nav_home, body.about #nav_about { */ Current nav styles */ }
我是这样做的:
Statistics
然后我所要做的就是在我的视图中添加{'active_tab': 'statistics'}
到我的上下文字典中.
如果您正在使用RequestContext
,则可以在模板中获取当前路径:
{{ request.path }}
在你看来:
from django.template import RequestContext def my_view(request): # do something awesome here return template.render(RequestContext(request, context_dict))
我从上面的nivhab获取了代码并删除了一些wierdness并将其变成了一个干净的模板标签,修改它以便/ account/edit /仍然会使/ account/tab处于活动状态.
#current_nav.py from django import template register = template.Library() @register.tag def current_nav(parser, 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]) class NavSelectedNode(template.Node): def __init__(self, url): self.url = url def render(self, context): path = context['request'].path pValue = template.Variable(self.url).resolve(context) if (pValue == '/' or pValue == '') and not (path == '/' or path == ''): return "" if path.startswith(pValue): return ' class="current"' return "" #template.html {% block nav %} {% load current_nav %} {% url home as home_url %} {% url signup as signup_url %} {% url auth_login as auth_login_url %}{% endblock %}
这只是Toba上面提出的css解决方案的一个变种:
在基本模板中包含以下内容:
然后在扩展基本用途的模板中:
{% block section %}show{% endblock %}
然后,您可以使用css根据body标签突出显示当前区域(例如,如果我们有一个id为nav-home的链接):
#section-home a#nav-home{ font-weight:bold; }