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


У меня есть база.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 определение для каждого из индексов.html, все такое.html, примерно.html и контакт.формат html. Каждый из этих шаблонов просто является производным от базы.html шаблон и установить свои собственные соответствующие названия и содержание.

Мой вопрос касается выше / stuff у меня есть класс= "current".

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

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

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

4 7

4 ответа:

Вот элегантный способ сделать это, который я скопировал откуда-то, и я только хотел бы вспомнить, где, чтобы я мог отдать им должное. 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 утверждения
  • добавление страниц в раздел просто работает [TM]
  • изменение внешнего вида вещей всегда означает только изменение CSS, а не разметки.

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

Эта идея легко распространяется и на другие ситуации, например. - Мне нужна ссылка на скачивание в боковой панели на каждой странице, кроме самих страниц загрузки."Вы можете сделать это в CSS следующим образом:
#section-download #sidebar #download-link {
    display: none;
}

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

Не использовал Django, но я имел дело с той же проблемой в Kohana (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>