7

我有一个包含链接列表的 base.html 模板。

例子:

   <div id="sidebar1">
        <ul>
        <li><a href="/" title="">Index</a></li>
        <li><a href="/stuff/" title="" class="current">Stuff</a></li>
        <li><a href="/about/" title="">About Me</a></li>
        <li><a href="/contact/" title="">Contact Me</a></li>
    </div>

然后我在views.py 中有一个index.html、stuff.html、about.html 和contact.html 的定义。这些模板中的每一个都简单地从 base.html 模板派生并设置各自的标题和内容。

我的问题是关于上述/stuff 我有一个 class="current"。

我想让我所在的当前页面具有该类属性。

我可以在每个视图中设置一个不同的变量,例如 current_page="about" 然后在模板中与{% ifequal %}每个链接的每个类元素中进行比较,但这似乎是重复工作(因为额外的视图变量)。

有没有更好的办法?也许如果有一种方法可以获取自动填充模板的视图函数名称,我不需要设置额外的变量?此外,它似乎确实有很多 ifequals。

4

4 回答 4

17

这是一种优雅的方法,我从某个地方复制了它,我只希望我能记住在哪里,所以我可以给他们功劳。8-)

id我为我的每个页面(或一个部分中的所有页面)分配一个,如下所示:

In index.html:    <body id='section-intro'>...
In faq.html:      <body id='section-faq'>...
In download.html: <body id='section-download'>...

然后是id相应的链接:

<li id='nav-intro'><a href="./">Introduction</a></li>
<li id='nav-faq'><a href="./faq.html">FAQ</a></li>
<li id='nav-download'><a href="./download.html">Download</a></li>

在 CSS 中,我设置了这样的规则:

#section-intro #nav-intro,
#section-faq #nav-faq,
#section-download #nav-download {
    font-weight: bold;
    /* And whatever other styles the current link should have. */
}

因此,这主要以声明性方式控制当前页面所属链接的样式。您可以在此处查看它的实际效果:http: //entrian.com/source-search/

一旦你设置了它,它就是一个非常干净和简单的系统,因为:

  • 您无需在链接中使用模板标记
  • 你最终不会使用大而丑陋的switch陈述或if / else / else陈述
  • 将页面添加到部分 Just Works [TM]
  • 改变事物的外观只意味着改变 CSS,而不是标记。

我没有使用 Django,但是这个系统可以在任何地方工作。在您的情况下,您“设置各自的标题和内容”还需要设置body id,并且不需要其他 Django 标记。

这个想法也很容易扩展到其他情况,例如。“除了下载页面本身,我希望每个页面的侧边栏中都有一个下载链接。” 你可以在 CSS 中这样做:

#section-download #sidebar #download-link {
    display: none;
}

而不必将条件模板标记放在侧边栏 HTML 中。

于 2009-06-21T16:01:38.020 回答
2

没有使用过 Django,但我在Kohana (PHP) 和 Rails 中处理过同样的问题。

我在 Kohana 做什么:

<li><a href="/admin/dashboard" <?= (get_class($this) == 'Dashboard_Controller') ? "class=\"active\"" : NULL ?>>Dashboard</a></li>
<li><a href="/admin/campaigns" <?= (get_class($this) == 'Campaigns_Controller') ? "class=\"active\"" : NULL ?>>Campaigns</a></li>
<li><a href="/admin/lists" <?= (get_class($this) == 'Lists_Controller') ? "class=\"active\"" : NULL ?>>Lists</a></li>

我在 Rails 中所做的事情:

<li><a href="/main" <%= 'class="active"' if (controller.controller_name == 'main') %>>Overview</a></li>
<li><a href="/notifications" <%= 'class="active"' if (controller.controller_name == 'notifications') %>>Notifications</a></li>
<li><a href="/reports" <%= 'class="active"' if (controller.controller_name == 'reports') %>>Reports</a></li>
于 2009-06-21T16:41:57.703 回答
1

我只看到了几种方法,同时避免重复 ifequals:

  1. Javascript。类似于(jQuery)的东西:

    var parts = window.location.pathname.split('/');
    var page = parts[parts.length-1];
    $('#sidebar1 a[href*=' + page + ']').addClass('current');
    
  2. 更改您的视图以包含带有相关标题和 URL 的页面列表,并在您的模板中创建一个 {% for %} 循环,该循环将遍历该列表,并添加一个 {% ifequal %}。

选项 2 是我的最爱。如果所有页面的逻辑都相同,并且只有模板不同,则可以考虑为每个页面使用 FlatPages 模型。如果逻辑不同,并且您需要不同的模型,则可以考虑使用某种菜单应用程序。一个无耻的插件:我有自己的菜单应用程序

于 2009-06-21T16:42:29.747 回答
1

如果添加request上下文处理器,则非常简单:

settings.py:

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.request',
    'django.contrib.auth.context_processors.auth'  # admin app wants this too
)

现在您可以访问HttpRequest包含请求路径的 。突出显示当前页面是检查路径是否与链接的目标匹配的简单问题,即您已经在那里:

<li><a class="{% if request.path == '/' %}current{% endif %}" href="/">Index</a></li>
<li><a class="{% if request.path == '/stuff/' %}current{% endif %}" href="/stuff/">Stuff</a></li>
<li><a class="{% if request.path == '/about/' %}current{% endif %}" href="/about/">About Me</a></li>
<li><a class="{% if request.path == '/contact/' %}current{% endif %}" href="/contact/">Contact Me</a></li>
于 2013-10-29T22:41:01.200 回答