Как насчет пользовательского тега, который вы используете для создания элемента навигации?
Ниже приводится имя URL, для которого должен быть создан элемент навигации, и текст, который он должен отображать. Он генерирует тег li с классом «selected», если путь указанного URL-адреса совпадает с текущим URL-адресом (в вашем TEMPLATE_CONTEXT_PROCESSORS
требуется 'django.core.context_processors.request'
). Внутри li он генерирует тег с путем URL, указанным url_name
. Содержит содержимое, указанное contents
.
Очевидно, что это может быть изменено для создания другой разметки для элемента навигации, как требуется.
Остальное можно сделать с помощью CSS.
Преимущества:
Недостатки:
Требуется 'django.core.context_processors.request'
Требуется указание URL, например, urlpatterns = patterns('django.views.generic.simple',
...
(r'^$', 'direct_to_template', {'template': 'index.html'}, 'index'),
...
)
. Это потенциально может быть сделано по-другому (например, передать в URL).
Не справляется со страницами, не полностью равными указанному, и поэтому не будет применять выбранный класс к li, если он находится на странице ниже в иерархии URL. Например, если я нахожусь на / products /, он выделит пункт навигации, указывающий на / products /. Если я нахожусь на / products / myProduct /, он не будет выделять ссылку / products /. Это можно закодировать, но это заставит людей использовать разумные ссылки. Например, измените присвоение additionalAttrs
на additionalAttrs = ' class=selected' if (context['request'].path.startswith(path) and path != '/') or (context['request'].path == path) else ''
.
Код:
from django import template
from django.core.urlresolvers import reverse
register = template.Library()
class NavNode(template.Node):
def __init__(self, url_name, contents):
self.url_name = url_name
self.contents = contents
def render(self, context):
path = reverse(self.url_name)
additionalAttrs = ' class=selected' if path == context['request'].path else ''
return '<li'+additionalAttrs+'><a href="'+path+'">'+self.contents+'</a></li>'
@register.tag
def nav_link(parser, token):
bits = token.split_contents()
if len(bits) == 3:
contents = bits.pop()
url_name = bits.pop()
else:
raise template.TemplateSyntaxError, "%r tag requires a single argument" % bits[0]
if contents[0] == contents[-1] and contents[0] in ('"', "'"):
contents = contents[1:-1]
return NavNode(url_name, contents)