【问题标题】:Django - Highlight Navigation based on current page?Django - 基于当前页面突出显示导航?
【发布时间】: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 navigation


【解决方案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>
            

            【讨论】:

              猜你喜欢
              • 2012-03-18
              • 1970-01-01
              • 2017-01-31
              • 2016-10-01
              • 1970-01-01
              • 1970-01-01
              • 2011-06-05
              • 1970-01-01
              相关资源
              最近更新 更多