Django - Выделить подсветку на основе текущей страницы?
Я создаю webapp, который имеет несколько основных разделов. Каждая секция имеет несколько подсекций. У меня есть файл main_nav.html
, который содержит навигацию для основного раздела. Это добавляется в файл HTML
с помощью команды {% include ... %}
в шаблоне base.html
. Кроме того, у меня есть несколько навигационных файлов sub-section, каждый из которых добавляется на любую страницу с той же командой {% include ... %}
.
Все навигационные бары очень просты, просто текст с тегами <a href...>
.
Я хочу выделить ссылку для текущего основного раздела и текущего подраздела. Поскольку этот webapp довольно большой, я надеялся каким-то образом сделать это, не добавляя информацию о странице. Кроме того, я хочу, чтобы он просто "работал" с расширением webapp, чтобы включить больше разделов и подразделов. Например, можно ли это сделать, посмотрев фактический URL-адрес? Я надеялся разместить это в самих файлах навигации и не должен загружать какую-либо переменную или что-то в каждом представлении django.
Итак, например, nav выглядит так:
(main ->) [Systems][Invoices][Work Orders][Admin]
(system sub-nav ->) [Owner][Billing][Contacts]
Итак, если я в разделе Billing
Systems
, я хочу, чтобы ссылка Systems
выделена жирным шрифтом, а ссылка Billing
была выделена жирным шрифтом (или какой-либо другой простой подсветкой)
Или:
(main ->) [Systems][Invoices][Work Orders][Admin]
(Work-Orders sub-nav ->) [Create New][Outstanding]
Если я в разделе Outstanding
Work Orders
, ссылка Work Orders
и ссылка Outstanding
должны быть выделены.
Любые идеи?
Ответы
Ответ 1
Предполагая, что вы используете render_to_response
с RequestContext
или используете метод 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>
Повторите, если необходимо, для каждой ссылки.
Ответ 2
Просто подумал, что я брошу свой подход, чтобы другие подумали, нашли ли они это в 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');
}
});
Очень просто, дает вам контроль над тем, какую ссылку выделить, добавив крошечный блок в свои шаблоны.
Ответ 3
В другом подобном вопросе, я видел jpwatts ', 110j, nivhab и Marcus Whybrow отвечает, но им все, кажется, не хватает чего-то: как насчет корневого пути? Почему он всегда активен?
Итак, я сделал другой способ, проще, что делает "контроллер" решает сам по себе, и я думаю, что он разрешает большинство больших проблем.
Вот мой пользовательский тег:
## 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-адресами или с корневым стр.
Ответ 4
Расширяя принятый ответ Криса, вы можете использовать тот факт, что язык шаблонов Django поддерживает in
для частичного сопоставления. Например, если у вас есть URL-адреса, например
/people/directory
/people/profiles/joe
/people/profiles/edit
и вы хотите, чтобы основной элемент "Люди" был выделен для всех этих случаев, используйте что-то вроде:
{% if "/people/" in request.path %}class="active"{% endif %}
Ответ 5
Развернувшись на ответе fabspro, здесь можно сделать это на основе URL-адресов страниц и с помощью ванильных 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
, но ссылка будет показана активной для всех grandchildren
в child1
. Любая специальная логика может быть написана на самом деле.