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]

所以如果我在SystemsBilling 部分,我希望链接Systems 加粗,链接Billing 加粗(或其他一些简单的突出显示)

或者:

(main ->)                 [Systems][Invoices][Work Orders][Admin]
(Work-Orders sub-nav ->)  [Create New][Outstanding]

如果我在Work OrdersOutstanding 部分,则需要突出显示链接Work Orders 和链接Outstanding

有什么想法吗?

【问题讨论】:

有一个中间件可以做到这一点,而且很容易插入...查看 django sn-ps 站点 也可以考虑这个github.com/hellysmile/django-activeurl(django 3 的分支:github.com/timgates42/django-activeurl 效果很好) 【参考方案1】:

假设您使用 render_to_responseRequestContext 或使用 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_responseRequestContext 时,变量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 - 基于当前页面突出显示导航?的主要内容,如果未能解决你的问题,请参考以下文章

如何正确构建突出当前页面的导航菜单

导航,突出显示当前页面

在自定义导航栏 wordpress 中突出显示当前页面

PHP 突出显示导航中的当前页面

PHP PHP包括导航,选择/突出显示当前页面

更改导航 ID 以突出显示当前页面 ASP.NET 的编程解决方案