7

我将 django 与 Twitter Bootstrap 一起使用。我当前的视图类似于提供的示例之一。看一下这个例子,可以想象用户点击侧边栏中的一个链接来查看不同的视图,每个视图都带有相同的侧边栏。可以想象选择的链接将被突出显示,就像使用代码的示例一样:

<li class="active"><a href="/sample/link/here/">Link</a></li>

活动类需要附加到正确的菜单项。我如何将这个“活动”类分配给正确的菜单项?最初,我尝试从我的视图中使用一个变量来用 jquery 分配它:

$(document).ready(function() {
    $("#{{ current_view }}_nav").addClass('active');
});

<li id="linkone_nav"><a href="/sample/link/here/">Link</a></li>

不过这似乎很麻烦。它要求我将 id 从视图传递给模板。还有很多 id 需要管理。是否有更好/更首选的方法来分配这个活动课程?

4

7 回答 7

7

我认为您#在示例代码中对 href 的使用使问题变得模糊不清。我假设您的真实场景是实际的真实链接,并根据活动 URL 自动突出显示它们。如果这是正确的,那么只需执行以下操作:

{% url something as url %}
<li{% if request.path == url %} class="active"{% endif %}><a href="{{ url }}">Link1</a></li>

其中,“something”是 urlpattern 或视图的虚线路径等的名称。显然,这假设您正在反转 URL,因此如果您使用的是静态 URL,则只需对其进行硬编码:

<li{% if request.path == "/my/full/url/path/" %} class="active"{% endif %}><a href="/my/full/url/path/">Link1</a></li>
于 2012-08-16T17:31:44.327 回答
7

如果您已将项目组织成一个base.html由其他模板扩展的模板,例如appname/pagename.html,您可以使用以模板为中心的方法来突出显示活动的导航元素。

这种方法为您提供了一些解耦优势,我已在此答案的末尾详细说明了这一点。

我发现这种方法对于处理在大部分或所有站点中保持相同的广泛导航项非常有用。对于更详细的导航元素,例如呈现从数据存储中收集的项目的动态列表,它可能不是一个合适的解决方案。

在您的base.html模板中,为每个导航元素添加一个块,为这些块提供唯一的名称:

<ul class="nav">
  <li class="{% block navbar_class-home %}{% endblock %}">
    <a href="#">Home</a>
  </li>
  <li class="{% block navbar_class-about %}{% endblock %}">
    <a href="#">About</a>
  </li>
  <li class="{% block navbar_class-pricing %}{% endblock %}">
    <a href="#">Pricing</a>
  </li>
</ul>

在您的appname/pagename.html模板中,如果您希望其中一个 nav 元素显示为活动状态,请覆盖使用active作为内容的相应块。例如,要突出显示“关于”项:

{% block navbar_class-about %} active {% endblock %}

当您使用呈现该模板的视图时,它将呈现如下:

<ul class="nav">
  <li class="">
    <a href="#">Home</a>
  </li>
  <li class=" active ">
    <a href="#">About</a>
  </li>
  <li class="">
    <a href="#">Pricing</a>
  </li>
</ul>

这提供了不依赖于 JavaScript 的初始呈现。(如果你正在做一个单页应用程序,你可以使用 JavaScript 修改导航栏类。)

对于许多(但不是全部)情况,这可能是与视图逻辑更好的分离表示:

  • 您可以修改视图以将站点导航数据附加到模板上下文,但这样做会强烈地将演示文稿与视图层耦合,并使创建可重用应用程序或集成第三方应用程序变得更加困难。

    视图已经在选择一个命名模板,这意味着您已经将一些与导航相关的信息传递给模板层。这可能就是你所需要的。

  • 您可以使用模板上下文处理器来获取有关视图的一些信息,但这只是将强耦合移动到系统的另一层,而不是留在模板层中。

于 2012-12-14T17:07:41.413 回答
2

更好的解决方案,更少的代码。与 Bootstrap 配合得很好。只需更改“addClass”查询以选择您的菜单项。

在 Javascript 上,创建此函数:

var highlight_menu = function(path) {
    /* Highlight current link */    
    $('.nav li').removeClass('active');
    $('.nav li:has(a[href="' + path + '"])').addClass('active')
};

在 base.html 上,使用当前路径调用 JS 函数:

<script>
    highlight_menu('{{request.path}}');
</script>
于 2013-07-24T21:15:17.550 回答
1

FWIW,Twitter Bootstrap 页面本身具有通过使用Scrollspy 插件提供的此功能。

否则,您可以只听菜单中的单击事件。

$('.nav').on('click', 'li:has(a[href^="#"])', function (e) {
  $('.nav li').removeClass('active');
  $(this).addClass('active');
});
于 2012-08-16T15:58:05.607 回答
0

为您的菜单制作一个包含片段:

<li class="{% if opt=='link1' %} active{% endif %}"><a href="#/?opt=link1">Link1</a></li>
<li class="{% if opt=='link2' %} active{% endif %}"><a href="#/?opt=link2">Link2</a></li>
<li class="{% if opt=='link3' %} active{% endif %}"><a href="#/?opt=link3">Link3</a></li>
...

将其包含在您的基本模板中:

{% include "menu.html" with opt=request.GET.opt %}

如您所见,您不需要使用 $( document ).ready(...) 。

不要忘记向您的 TEMPLATE_CONTEXT_PROCESSORS 添加请求:

TEMPLATE_CONTEXT_PROCESSORS = (
  # ...
  'django.core.context_processors.request',
  # ...
)
于 2012-08-16T15:52:12.937 回答
0

为此,我使用了一个 simple_tag。也许有人会发现它有帮助。

创建一个文件 isactive.py 并将其放在应用模板路径级别的 templatetags 目录中。

from django import template
from django import urls
register = template.Library()

@register.simple_tag
def isactive(page_name, request_url):
    rev_url = ''
    try:     
        rev_url = urls.reverse(page_name)
    except:
        return ''
    if (rev_url == request_url):
            return 'active'
    return ''

在你的 html 模板中

{% load isactive %}

加载静态并在您的菜单中后

<a href="{% url 'my_table_list' %}" class="nav-link {% isactive 'my_table_list' request.path %}">

渲染时 - django 正在执行函数 isactive 其中第一个参数是页面的名称,另一个是路径。在 isactive 函数内部,名称被解析和比较。当它匹配时,将返回活动字符串并将其放置在生成的 html 中。您必须在每个导航链接中都调用该调用。

页面名称取自应用程序 urls.py 中的 urlpatterns

urlpatterns = (
    ...
    path("my_table/list/", views.mytableListView.as_view(), name="my_table_list"),
    ....
于 2021-07-01T08:42:27.253 回答
0

您可以考虑以下方法来解决 Django 中的问题。

它可以在不使用 javascript 的情况下正常工作。只需使用纯 Django,您就应该能够解决大多数需要突出显示菜单选项的情况。

在此示例中,我使用的是 Bootstrap 4,但这并不重要。你可以使用自己的 CSS,你会没事的。这里的想法只是展示使用request.resolver_match.url_name 作为 url_name来实现您所需要的。

{% with request.resolver_match.url_name as url_name %}
   <ul class="navbar-nav mr-auto">
      <li class="{% if url_name == 'your url' %}nav-item active{% else %}nav-item{% endif %}">
       <a class="nav-link" href="{% url 'your url 1' %}">Menu option 1</a>
      </li>
      <li class="{% if url_name == 'your url' %}nav-item active{% else %}nav-item{% endif %}">
       <a class="nav-link" href="{% url 'your url 2' %}">Menu option 2</a>
      </li>
   </ul>
{% endwith %}
于 2020-10-20T03:47:26.090 回答