Django - 基于当前页面突出显示导航?
Posted
技术标签:
【中文标题】Django - 基于当前页面突出显示导航?【英文标题】:Django - Highlight Navigation based on current page? 【发布时间】:2011-12-01 16:55:29 【问题描述】:我正在构建一个包含几个主要部分的 web 应用程序。每个部分都有几个子部分。我有一个main_nav.html
文件,其中包含主要部分的导航。这将使用base.html
模板中的% include ... %
命令添加到基于HTML
的文件中。此外,我有几个子部分导航文件,每个文件都使用相同的% include ... %
命令添加到任何给定页面。
所有的导航栏都非常简单,只是带有<a href...>
标签的文本。
我想突出显示当前主要部分和当前子部分的链接。由于这个 webapp 相当大,我希望在不添加特定页面信息的情况下以某种方式做到这一点。另外,我希望它只是“工作”,因为 web 应用程序扩展为包含更多部分和子部分。例如,这可以通过查看实际使用的 URL 来完成吗?我希望把它放在导航文件本身中,而不必在每个 django 视图中加载一些变量或任何东西。
例如,导航看起来像这样:
(main ->) [Systems][Invoices][Work Orders][Admin]
(system sub-nav ->) [Owner][Billing][Contacts]
所以如果我在Systems
的Billing
部分,我希望链接Systems
加粗,链接Billing
加粗(或其他一些简单的突出显示)
或者:
(main ->) [Systems][Invoices][Work Orders][Admin]
(Work-Orders sub-nav ->) [Create New][Outstanding]
如果我在Work Orders
的Outstanding
部分,则需要突出显示链接Work Orders
和链接Outstanding
。
有什么想法吗?
【问题讨论】:
有一个中间件可以做到这一点,而且很容易插入...查看 django sn-ps 站点 也可以考虑这个github.com/hellysmile/django-activeurl(django 3 的分支:github.com/timgates42/django-activeurl 效果很好) 【参考方案1】:假设您使用 render_to_response
和 RequestContext
或使用 render
方法或 Django 1.3 的基于类的视图,您将在模板中使用请求对象。从那里,只需访问当前路径并将其与预期值进行比较就很简单了:
<a href="/some/path/to/be/highlighted/"% if request.path == '/some/path/to/be/highlighted/' % class="active"% endif %>Some Link</a>
在 Django 1.3 中,我喜欢保存冗余并使用 as
运算符进行 URL 查找:
% url 'some_urlpattern_name' as url %
<a href=" url "% if request.path == url % class="active"% endif %>Some Link</a>
根据需要对每个链接重复。
【讨论】:
并使用CSS高亮父菜单项 感谢您的回复。这似乎是一种巧妙的方法。但是,当我使用render_to_response
和RequestContext
时,变量request.path
似乎是空的。难道我做错了什么?如果我将 request.path
放在我的链接上方只是为了查看那里存储的内容,它是空的。
好的,我想我明白了。我必须将这些行添加到我的settings.py
文件中:from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS
(换行)TEMPLATE_CONTEXT_PROCESSORS += (
(换行)'django.core.context_processors.request',)
。我必须承认我不是 100% 确定我做对了,但是有了这些行,我现在可以在模板中使用 request.get_full_path
。
对不起。是的,您还需要模板上下文处理器。这是一个设置后忘记设置,所以我通常会......忘记它;)
是否可以进行反向 URL 查找而不是硬编码要搜索的路径?【参考方案2】:
扩展 Chris 接受的答案,您可以使用 Django 模板语言支持 in
的事实进行部分匹配。因此,例如,如果您有类似的网址
/people/directory
/people/profiles/joe
/people/profiles/edit
如果您希望在所有这些情况下突出显示主要的“人物”导航元素,请使用以下内容:
% if "/people/" in request.path %class="active"% endif %
【讨论】:
【参考方案3】:只是想我会提出我的方法供其他人考虑,如果他们在 google 中找到这个。
在我的模板中我有这样的东西:
% block pagename %homepage% endblock %
然后在我的主模板中,类似这样的内容(以便继承模板中的页面名称可用于呈现的页面):
<span id="_pageName" style="display:none">% block pagename %% endblock %</span>
我的链接如下所示:
<li data-link-name="homepage"><a href="% url "pages:home" %">Home</a></li>
您只需要一点 javascript 在页面加载时将您的 CSS 类应用到正确的链接。我的看起来像这样:
$(function()
var pageName = document.getElementById('_pageName');
if (pageName != null) pageName = pageName.innerHTML;
else pageName = '';
if (pageName.length > 0)
$("li[data-link-name='" + pageName + "']").addClass('active');
);
非常简单,您可以通过在模板中添加一个小块来控制要突出显示的链接。
【讨论】:
【参考方案4】:In an other similar question, 我见过jpwatts'、110j's、nivhab's & Marcus Whybrow's 的答案,但他们似乎都缺少一些东西:根路径呢?为什么它总是活跃的?
所以我做了另一种更简单的方法,让“控制器”自行决定,我认为它可以解决大部分大问题。
这是我的自定义标签:
## myapp_tags.py
@register.simple_tag
def nav_css_class(page_class):
if not page_class:
return ""
else:
return page_class
然后,“控制器”声明需要的 CSS 类(事实上,最重要的是它向模板声明了它的存在)
## views.py
def ping(request):
context=
context["nav_ping"] = "active"
return render(request, 'myapp/ping.html',context)
最后,我在导航栏中渲染它:
<!-- sidebar.html -->
% load myapp_tags %
...
<a class="% nav_css_class nav_home %" href="% url 'index' %">
Accueil
</a>
<a class="% nav_css_class nav_candidats %" href="% url 'candidats' %">
Candidats
</a>
<a class="% nav_css_class nav_ping %" href="% url 'ping' %">
Ping
</a>
<a class="% nav_css_class nav_stat %" href="% url 'statistiques' %">
Statistiques
</a>
...
所以每个页面都有自己的 nav_css_class
值要设置,如果设置了,模板会呈现为活动状态:在模板上下文中不需要 request
,没有 URL 分配,也没有更多关于多 URL 页面或根的问题页面。
【讨论】:
【参考方案5】:比使用 as
运算符(当前最佳答案)更简单的是,将以下 if
放在您想要进行的任何 HTML 或 CSS 更改以将页面显示为活动状态:
% if request.resolver_match.url_name == 'your_active_url_pattern_name' %
【讨论】:
【参考方案6】:扩展 fabspro 的答案,这是一种基于页面 url 和 vanilla js 的方法。
<div id="navbar">
<ul>
<li data-link-name="home">
<a href="% url 'home' %"><span>Home</span></a>
</li>
<li data-link-name="parent">
<a href="% url 'myapp:index' %"><span>Parent</span></a>
</li>
<li data-link-name="child1">
<a href="/myapp/child1/grandchild1"><span>Child 1</span></a>
</li>
</ul>
</div>
<script>
var path = location.pathname;
if (path == "/")
pageName = "home";
else if (path.startsWith("/myapp/child1"))
pageName = "child1";
else if (path.startsWith("/myapp"))
pageName = "parent";
document.querySelector("li[data-link-name='" + pageName + "']").classList += "active";
</script>
这里有很大的灵活性。例如,上面的 Parent
链接将针对其中的所有 url 突出显示,/child1
除外。 Child 1
链接会将用户带到/grandchild1
页面,但对于child1
中的所有grandchildren
,该链接将显示为活动状态。真的可以编写任何类型的自定义逻辑。
【讨论】:
【参考方案7】:如果您想使用 unicode 处理复杂的 url,请不要忘记使用 iriencode
(https://docs.djangoproject.com/en/dev/ref/templates/builtins/#iriencode)
% url 'your_view_name_defined_in_urls.py' possible_attribute as url %
<a class="% if request.path|iriencode == url %active% endif %" href=" url ">
Your label
</a>
【讨论】:
以上是关于Django - 基于当前页面突出显示导航?的主要内容,如果未能解决你的问题,请参考以下文章