Комментарии 11
ИМХО, корректнее реализовывать данную задачу следующим образом:
Разумеется не забываем подключить django.core.context_processors.request
{% url 'menu_1' as menu_url_1 %}
{% url 'menu_2' as menu_url_2 %}
{% ifequal request.path menu_url_1 %}menu 1 is active{% endifequal %}
{% ifequal request.path menu_url_2 %}menu 2 is active{% endifequal %}
Разумеется не забываем подключить django.core.context_processors.request
На дворе django 1.6, а вы до сих пор пользуетесь
Заодно вот такой велосипед:
ifequal
? Серьезно?Заодно вот такой велосипед:
_urls = (
(reverse_lazy('app1.index'), u'App 1'),
(reverse_lazy('app2.index'), u'App 2'),
(reverse_lazy('app3.index'), u'App 3'),
)
@register.inclusion_tag('menu.html', takes_context=True)
def navigation_menu(context):
request = context['request']
urls = []
full_path = request.get_full_path()
for href, name in _urls:
is_current = full_path.startswith(href)
urls.append([href, name, is_current])
return {
'urls': urls,
}
На дворе django 1.6, а вы до сих пор пользуетесь ifequal? Серьезно?
Я знаю про {% if a == b %}, но вот момент когда ifequal признан устаревшим, честно говоря, я пропустил, тем более что в dev версии доков об этом ни слова (разве что упомянуто об эквивалентности этих записей и всё). Так что дело тут просто в привычке, хотя да, через if запись будет получаться на несколько символов короче.
Я делаю так:
templatetags/navigation.py
template.html
templatetags/navigation.py
import re
from django import template
register = template.Library()
@register.simple_tag
def active(request, pattern):
if re.search(pattern, request.path):
return 'active'
return ''
template.html
{% load navigation %}
... class="first {% active request "^/url1/" %}" ...
... class="{% active request "^/url2/" %}" ...
Хм. Парсить хтмл, регулярками находить нужный пункт навигации ради того чтобы его подсветить… Вам не кажется что это оверкил?! Я правда вот так сразу не предложу простого и универсального решения. Ваш вариант я пожалуй применял бы только в случае когда менюшки автоматически генерируются.
Когдато давно в своем проектике я решил эту проблему на уровне наследования в шаблонах. В главном шаблоне
а в шаблонах отдельных страниц просто доблял
Тупое решение в лоб, но для небольшого проекта в самый раз. Сейчас я бы поискал более изящное решение.
Когдато давно в своем проектике я решил эту проблему на уровне наследования в шаблонах. В главном шаблоне
...
<li class="{%block about%}{%endblock%}"><a href="/">О проекте</a></li>
<li class="{%block search%}{%endblock%}"><a href="/search">Поиск</a></li>
<li class="{%block contacts%}{%endblock%}"><a href="/contact">Обратная связь</a></li>
...
а в шаблонах отдельных страниц просто доблял
{%block contacts%} active{%endblock%}
Тупое решение в лоб, но для небольшого проекта в самый раз. Сейчас я бы поискал более изящное решение.
Неужели никто не использует django-treenav?
Более сложный вариант. Пользуюсь им уже года два
import re
from django import template
register = template.Library()
@register.simple_tag
def active_tag(request, patterns, out='selected'):
"""
usage:
<a class="url{% active_tag request "default /home/" %}" href="#">url item 1</a>
-> <a class="url seleced">url item 1</a>
<a class="url{% active_tag request "/posts/ /allposts/" "custom-css" %}" href="#">url item 2</a>
-> <a class="url custom-css">url item 2</a>
{% active_tag request '^/account/-/(\w+)/$ ^/account/-/(\w+)/edit/$ ^/account/-/(\w+)/password/$' 'class="selected"'%}
{% active_tag request obj.get_absolute_url %}
"""
if "default" in patterns.split() and request.path == '/':
return " %s" % out
else:
return " %s" % out if len([p for p in patterns.split()
if re.search(p, request.path) ]) else ''
0) таки тянет на оверкилл
1) а как поступать со вложенной навигацией и вообще случаями менее очевидными, чем request.url === page.url?
2) свой велосипед — хорошо, но не стоило бы начать с обзора существующих? в том числе и эту статью…
1) а как поступать со вложенной навигацией и вообще случаями менее очевидными, чем request.url === page.url?
2) свой велосипед — хорошо, но не стоило бы начать с обзора существующих? в том числе и эту статью…
Я пользуюсь menus из django-cms
docs.django-cms.org/en/2.4.3/getting_started/navigation.html
docs.django-cms.org/en/2.4.3/getting_started/navigation.html
А почему все так любят привязываться к конкретному URL, типа {% active request "^/url1/" %}, забывая про reverse()? Хардкодинг URL — зло.
Вот и мой двухколёсный друг:
В шаблоне:
Как уже говорили выше, парсить собственноручно написанный шаблон (не какой-то там чужой сайт!) — это точно оверкилл. Напишите шаблон так, чтоб не парсить.
Вот и мой двухколёсный друг:
@register.filter
def is_current_page(request, param):
params = param.split(',')
name = params[0]
args, kwargs, as_var = parse_args_and_kwargs(params[1:])
# Do not mix args and kwargs in reverse() - it is forbidden!
if args:
return request.path == reverse(name, args=args)
elif kwargs:
return request.path == reverse(name, kwargs=kwargs)
else:
return request.path == reverse(name)
В шаблоне:
{% if request|is_current_page:'shop/product,id=1' %} active {% endif %}
Как уже говорили выше, парсить собственноручно написанный шаблон (не какой-то там чужой сайт!) — это точно оверкилл. Напишите шаблон так, чтоб не парсить.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Навигация в шаблонах Django