Джанго:Есть ли лучший способ выделить жирным шрифтом ссылку на текущую страницу

StackOverflow https://stackoverflow.com/questions/1024168

Вопрос

У меня есть 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".

Я бы хотел, чтобы текущая страница, на которой я нахожусь, имела этот атрибут class .

Я мог бы установить другую переменную в каждом представлении, например current_page="about", а затем выполнить сравнение в шаблоне с {% ifequal %} в каждом элементе класса каждой ссылки , но это похоже на дублирующую работу (из-за дополнительной переменной view).

Есть ли лучший способ?Может быть, если есть способ получить имя функции просмотра, из которого шаблон был заполнен автоматически, мне не нужно было бы устанавливать дополнительную переменную?Кроме того, это действительно похоже на множество ifequals.

Это было полезно?

Решение

Вот элегантный способ сделать это, который я откуда-то скопировал и хотел бы только вспомнить, откуда, чтобы отдать им должное.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/

Это очень чистая и простая система, как только вы ее настроите, потому что:

  • Вам не нужно возиться с разметкой шаблона в ваших ссылках
  • Вы не заканчиваете тем, что используете big ugly (большие уродливые) switch заявления или if / else / else заявления
  • Добавление страниц в раздел Просто работает [TM]
  • Изменение внешнего вида вещей всегда означает изменение только CSS, а не разметки.

Я не использую Django, но эта система работает где угодно.В вашем случае, когда вы "устанавливаете их собственные соответствующие заголовки и содержимое", вам также необходимо установить body id, и никакой другой разметки Django не требуется.

Эта идея легко распространяется и на другие ситуации, например."Я хочу, чтобы ссылка на скачивание была на боковой панели на каждой странице, кроме самих страниц загрузки". Вы можете сделать это в CSS следующим образом:

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

вместо того, чтобы помещать условную разметку шаблона в боковую панель HTML.

Другие советы

Не использовал Django, но я сталкивался с той же проблемой в Кохана (PHP) и Rails.

Что я делаю в Кохане:

<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>

Я вижу только пару способов сделать это, избегая при этом повторных 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 для каждой из ваших страниц.Если логика отличается, и вам нужны другие модели, вы могли бы рассмотреть возможность использования какого-либо приложения с меню.Бесстыдная пробка:У меня есть мое собственное приложение для управления

Если вы добавите 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>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top