Я знаю, что этот вопрос слишком стар, но я не видел никакой реализации, подобной моей. Эта версия основана на символе преобразования Шварца .
function sortByAttribute(array, ...attrs) {
// generate an array of predicate-objects contains
// property getter, and descending indicator
let predicates = attrs.map(pred => {
let descending = pred.charAt(0) === '-' ? -1 : 1;
pred = pred.replace(/^-/, '');
return {
getter: o => o[pred],
descend: descending
};
});
// schwartzian transform idiom implementation. aka: "decorate-sort-undecorate"
return array.map(item => {
return {
src: item,
compareValues: predicates.map(predicate => predicate.getter(item))
};
})
.sort((o1, o2) => {
let i = -1, result = 0;
while (++i < predicates.length) {
if (o1.compareValues[i] < o2.compareValues[i]) result = -1;
if (o1.compareValues[i] > o2.compareValues[i]) result = 1;
if (result *= predicates[i].descend) break;
}
return result;
})
.map(item => item.src);
}
Вот пример того, как его использовать:
let games = [
{ name: 'Pako', rating: 4.21 },
{ name: 'Hill Climb Racing', rating: 3.88 },
{ name: 'Angry Birds Space', rating: 3.88 },
{ name: 'Badland', rating: 4.33 }
];
// sort by one attribute
console.log(sortByAttribute(games, 'name'));
// sort by mupltiple attributes
console.log(sortByAttribute(games, '-rating', 'name'));
Я использую шаблонное наследование для настройки навигации. Например:
base.html
<html>
<head>...</head>
<body>
...
{% block nav %}
<ul id="nav">
<li>{% block nav-home %}<a href="{% url home %}">Home</a>{% endblock %}</li>
<li>{% block nav-about %}<a href="{% url about %}">About</a>{% endblock %}</li>
<li>{% block nav-contact %}<a href="{% url contact %}">Contact</a>{% endblock %}</li>
</ul>
{% endblock %}
...
</body>
</html>
about.html
{% extends "base.html" %}
{% block nav-about %}<strong class="nav-active">About</strong>{% endblock %}
Спасибо за Ваши ответы до сих пор, мужскую уборную. Я пошел для чего-то немного отличающегося снова..
В моем шаблоне:
<li{{ link1_active }}>...link...</li>
<li{{ link2_active }}>...link...</li>
<li{{ link3_active }}>...link...</li>
<li{{ link4_active }}>...link...</li>
, Как только я удался, какая страница я иду в логике (обычно в urls.py), я передаю class="selected"
как часть контекста под правильным именем к шаблону.
, Например, если я нахожусь на link1 странице, я добавлю {'link1_active':' class="selected"'}
к контексту для шаблона, чтобы выкопать и ввести.
Это, кажется, работает, и это справедливо чисто.
Редактирование: для хранения HTML от моего контроллера/представления я изменил это немного:
<li{% if link1_active %} class="selected"{% endif %}>...link...</li>
<li{% if link2_active %} class="selected"{% endif %}>...link...</li>
...
Это делает шаблон немного менее читаемым, но я соглашаюсь, лучше не протолкнуть необработанный HTML из файла URL.
Я делаю это как это:
<a class="tab {% ifequal active_tab "statistics" %}active{% endifequal %}" href="{% url Member.Statistics %}">Statistics</a>
и затем все, что я должен сделать, по моему мнению, добавляют {'active_tab': 'statistics'}
к моему словарю контекста.
, Если Вы используете RequestContext
, можно получить текущий путь в шаблоне как:
{{ request.path }}
И в Вашем представлении:
from django.template import RequestContext
def my_view(request):
# do something awesome here
return template.render(RequestContext(request, context_dict))
Вы могли использовать обратная функция с соответствующими параметрами для получения текущего URL.
Вы могли применить класс или идентификатор к элементу тела страницы, а не к определенному военно-морскому объекту.
HTML:
<body class="{{ nav_class }}">
CSS:
body.home #nav_home,
body.about #nav_about { */ Current nav styles */ }
Мне понравилась чистота 110j выше, таким образом, я взял большую часть из нее и осуществил рефакторинг для решения этих 3 проблем, которые я имел с нею:
Здесь, это:
tags.py:
from django import template
register = template.Library()
@register.tag
def active(parser, token):
args = token.split_contents()
template_tag = args[0]
if len(args) < 2:
raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
return NavSelectedNode(args[1:])
class NavSelectedNode(template.Node):
def __init__(self, patterns):
self.patterns = patterns
def render(self, context):
path = context['request'].path
for p in self.patterns:
pValue = template.Variable(p).resolve(context)
if path == pValue:
return "active" # change this if needed for other bootstrap version (compatible with 3.2)
return ""
urls.py:
urlpatterns += patterns('',
url(r'/ base.html:
{% load tags %}
{% url home_url_name as home %}
{% url services_url_name as services %}
{% url contact_url_name as contact %}
{% url contact2_url_name as contact2 %}
<div id="navigation">
<a class="{% active request home %}" href="home">Home</a>
<a class="{% active request services %}" href="services">Services</a>
<a class="{% active request contact contact2 %}" href="contact">Contact</a>
</div>
, view_home_method, {}, name='home_url_name'),
url(r'/services/ base.html:
{% load tags %}
{% url home_url_name as home %}
{% url services_url_name as services %}
{% url contact_url_name as contact %}
{% url contact2_url_name as contact2 %}
<div id="navigation">
<a class="{% active request home %}" href="home">Home</a>
<a class="{% active request services %}" href="services">Services</a>
<a class="{% active request contact contact2 %}" href="contact">Contact</a>
</div>
, view_services_method, {}, name='services_url_name'),
url(r'/contact/ base.html:
{% load tags %}
{% url home_url_name as home %}
{% url services_url_name as services %}
{% url contact_url_name as contact %}
{% url contact2_url_name as contact2 %}
<div id="navigation">
<a class="{% active request home %}" href="home">Home</a>
<a class="{% active request services %}" href="services">Services</a>
<a class="{% active request contact contact2 %}" href="contact">Contact</a>
</div>
, view_contact_method, {}, name='contact_url_name'),
url(r'/contact/ base.html:
{% load tags %}
{% url home_url_name as home %}
{% url services_url_name as services %}
{% url contact_url_name as contact %}
{% url contact2_url_name as contact2 %}
<div id="navigation">
<a class="{% active request home %}" href="home">Home</a>
<a class="{% active request services %}" href="services">Services</a>
<a class="{% active request contact contact2 %}" href="contact">Contact</a>
</div>
, view_contact2_method, {}, name='contact2_url_name'),
)
base.html:
{% load tags %}
{% url home_url_name as home %}
{% url services_url_name as services %}
{% url contact_url_name as contact %}
{% url contact2_url_name as contact2 %}
<div id="navigation">
<a class="{% active request home %}" href="home">Home</a>
<a class="{% active request services %}" href="services">Services</a>
<a class="{% active request contact contact2 %}" href="contact">Contact</a>
</div>
Вам не нужно, если сделать это, взглянуть на следующий код:
tags.py
@register.simple_tag
def active(request, pattern):
import re
if re.search(pattern, request.path):
return 'active'
return ''
urls.py
urlpatterns += patterns('',
(r'/ base.html
{% load tags %}
{% url 'home_url_name' as home %}
{% url 'services_url_name' as services %}
{% url 'contact_url_name' as contact %}
<div id="navigation">
<a class="{% active request home %}" href="{{ home }}">Home</a>
<a class="{% active request services %}" href="{{ services }}">Services</a>
<a class="{% active request contact %}" href="{{ contact }}">Contact</a>
</div>
вот именно. для реализации детали взглянули на:
gnuvince.wordpress.com
110j.wordpress.com
, view_home_method, 'home_url_name'),
(r'/services/ base.html
{% load tags %}
{% url 'home_url_name' as home %}
{% url 'services_url_name' as services %}
{% url 'contact_url_name' as contact %}
<div id="navigation">
<a class="{% active request home %}" href="{{ home }}">Home</a>
<a class="{% active request services %}" href="{{ services }}">Services</a>
<a class="{% active request contact %}" href="{{ contact }}">Contact</a>
</div>
вот именно. для реализации детали взглянули на:
gnuvince.wordpress.com
110j.wordpress.com
, view_services_method, 'services_url_name'),
(r'/contact/ base.html
{% load tags %}
{% url 'home_url_name' as home %}
{% url 'services_url_name' as services %}
{% url 'contact_url_name' as contact %}
<div id="navigation">
<a class="{% active request home %}" href="{{ home }}">Home</a>
<a class="{% active request services %}" href="{{ services }}">Services</a>
<a class="{% active request contact %}" href="{{ contact }}">Contact</a>
</div>
вот именно. для реализации детали взглянули на:
gnuvince.wordpress.com
110j.wordpress.com
, view_contact_method, 'contact_url_name'),
)
base.html
{% load tags %}
{% url 'home_url_name' as home %}
{% url 'services_url_name' as services %}
{% url 'contact_url_name' as contact %}
<div id="navigation">
<a class="{% active request home %}" href="{{ home }}">Home</a>
<a class="{% active request services %}" href="{{ services }}">Services</a>
<a class="{% active request contact %}" href="{{ contact }}">Contact</a>
</div>
вот именно. для реализации детали взглянули на:
gnuvince.wordpress.com
110j.wordpress.com
У меня есть несколько меню на одной странице, которые создаются динамически через цикл. Посты выше, относящиеся к контексту, дали мне быстрое решение. Надеюсь, это кому-нибудь поможет. (Я использую это в дополнение к активному тегу шаблона - мое исправление решает динамическую проблему). Это выглядит как глупое сравнение, но это работает. Я решил назвать переменные active_something-уникальные и что-то уникальные, таким образом, это работает с вложенными меню.
Вот часть представления (достаточно, чтобы понять, что я делаю):
def project_list(request, catslug):
"render the category detail page"
category = get_object_or_404(Category, slug=catslug, site__id__exact=settings.SITE_ID)
context = {
'active_category':
category,
'category':
category,
'category_list':
Category.objects.filter(site__id__exact=settings.SITE_ID),
}
И это из template:
<ul>
{% for category in category_list %}
<li class="tab{% ifequal active_category category %}-active{% endifequal %}">
<a href="{{ category.get_absolute_url }}">{{ category.cat }}</a>
</li>
{% endfor %}
</ul>
Мое решение состояло в том, чтобы написать простой контекстный процессор для установки переменной на основе пути запроса:
def navigation(request):
"""
Custom context processor to set the navigation menu pointer.
"""
nav_pointer = ''
if request.path == '/':
nav_pointer = 'main'
elif request.path.startswith('/services/'):
nav_pointer = 'services'
elif request.path.startswith('/other_stuff/'):
nav_pointer = 'other_stuff'
return {'nav_pointer': nav_pointer}
(Дон ' Не забудьте добавить свой собственный процессор в TEMPLATE_CONTEXT_PROCESSORS в settings.py.)
Затем в базовом шаблоне я использую тег ifequal для каждой ссылки, чтобы определить, добавлять ли «активный» класс. Конечно, этот подход строго ограничен гибкостью вашей структуры путей, но он работает для моего относительно скромного развертывания.
Я просто хотел поделиться своим незначительным улучшением в сообщении nivhab. В моем приложении у меня есть поднавигации, и я не хотел скрывать их, используя только CSS, поэтому мне нужен был какой-то тег «если» для отображения поднавигации для элемента или нет.
from django import template
register = template.Library()
@register.tag
def ifnaviactive(parser, token):
nodelist = parser.parse(('endifnaviactive',))
parser.delete_first_token()
import re
args = token.split_contents()
template_tag = args[0]
if len(args) < 2:
raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
return NavSelectedNode(args[1:], nodelist)
class NavSelectedNode(template.Node):
def __init__(self, patterns, nodelist):
self.patterns = patterns
self.nodelist = nodelist
def render(self, context):
path = context['request'].path
for p in self.patterns:
pValue = template.Variable(p).resolve(context)
if path == pValue:
return self.nodelist.render(context)
return ""
Вы можете использовать это в основном таким же образом. в качестве активного тега:
{% url product_url as product %}
{% ifnaviactive request product %}
<ul class="subnavi">
<li>Subnavi item for product 1</li>
...
</ul>
{% endifnaviactive %}
Я взял код из приведенного выше нивхаба, удалил некоторые странности и превратил его в чистый тег шаблона, изменив его так, чтобы / account / edit / по-прежнему активировал / account / tab.
#current_nav.py
from django import template
register = template.Library()
@register.tag
def current_nav(parser, token):
import re
args = token.split_contents()
template_tag = args[0]
if len(args) < 2:
raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
return NavSelectedNode(args[1])
class NavSelectedNode(template.Node):
def __init__(self, url):
self.url = url
def render(self, context):
path = context['request'].path
pValue = template.Variable(self.url).resolve(context)
if (pValue == '/' or pValue == '') and not (path == '/' or path == ''):
return ""
if path.startswith(pValue):
return ' class="current"'
return ""
#template.html
{% block nav %}
{% load current_nav %}
{% url home as home_url %}
{% url signup as signup_url %}
{% url auth_login as auth_login_url %}
<ul class="container">
<li><a href="{{ home_url }}"{% current_nav home_url %} title="Home">Home</a></li>
<li><a href="{{ auth_login_url }}"{% current_nav auth_login_url %} title="Login">Login</a></li>
<li><a href="{{ signup_url }}"{% current_nav signup_url %} title="Signup">Signup</a></li>
</ul>
{% endblock %}
Это всего лишь вариант решения css, предложенного Тобой выше:
Включите следующее в ваш базовый шаблон:
<body id="section-{% block section %}home{% endblock %}">
Затем в ваши шаблоны, которые расширяют базовое использование:
{% block section %}show{% endblock %}
Затем вы можете использовать css для выделения текущей области на основе тега body (например, если у нас есть ссылка с идентификатором nav-home):
#section-home a#nav-home{
font-weight:bold;
}