Ответ 1
Вы пробовали тег шаблона {% with%}?
{% block content %}
{% with 'myvar' as expectedVarName %}
{{block.super}}
{% endwith %}
{% endblock content %}
У меня есть шаблоны этого стиля
project
- main_templates (including nav bar)
-- app1
--- app1_base_template
--- app1_templates
-- app2
--- app2_base_template
--- app2_templates
Поэтому при рендеринге app2_templates расширяет файл app2_base_template, который расширяет main_template.
Мне нужно сделать, чтобы соответствующий элемент навигации был выделен жирным шрифтом при визуализации шаблона app2 (чтобы показать пользователя, где он).
Проще всего было бы, если бы я мог передать переменную в части {% block xxx%}. Возможно ли это?
Какие еще общие способы существуют?
Вы пробовали тег шаблона {% with%}?
{% block content %}
{% with 'myvar' as expectedVarName %}
{{block.super}}
{% endwith %}
{% endblock content %}
Нет прямого способа передать переменную в дереве наследования шаблона так, как вы описываете. Способ, которым люди внедряют навигационные панели, которые выделяют текущую страницу, часто корректируется по характеру самого сайта. Тем не менее, я видел два общих подхода:
Низкотехнологичный подход
Передайте переменную в контексте шаблона, которая указывает, какая вкладка активна:
# in views.py
def my_view(request):
return render_to_response('app2_template.html', {"active_tab": "bar"},
<!-- Parent template -->
<div id="navigation">
<a href="/foo" {% ifequal active_tab "foo" %}class="active"{% endifequal %}>Foo</a>
<a href="/bar" {% ifequal active_tab "bar" %}class="active"{% endifequal %}>Bar</a>
</div>
Высокотехнологичный подход
Внедрите пользовательский тег шаблона, чтобы отобразить панель навигации. Попросите тег взять переменную, которая указывает, какой раздел активен:
<!-- Parent template -->
<div id="navigation">{% block mainnav %}{% endblock %}</div>
<!-- any child template -->
{% load my_custom_nav_tag %}
{% block mainnav %}{% my_custom_nav_tag "tab_that_is_active" %}{% endblock %}
Вы можете сходить с ума оттуда. Вы можете обнаружить, что кто-то уже реализовал что-то, что будет работать на вас на djangosnippets.org.
Переменные из родительского шаблона автоматически включаются в область дочерних элементов. В вашем заголовке говорится, что вы хотите передать переменную TO родительскому, что не имеет смысла, поскольку вы не можете определить переменные в шаблонах. Если вам нужна переменная в родительском и дочернем, просто объявите ее в представлении.
Неспособность передать аргументы при включении шаблона является одним из многих недостатков системы шаблонов Django.
Мне приходилось сталкиваться с почти одинаковой проблемой: глубоко вложенные шаблоны, необходимые для того, чтобы родительские шаблоны могли форматировать/выделять по-разному.
Возможные решения:
Используйте подпрограмму "суперконтекст", которая устанавливает количество значений на основе того, где вы находитесь в иерархии. То есть super_context = MySuperContext (запрос, другие, значения и т.д.), где super_context - это dict, который вы передаете в представление (или в RequestContext). Это самый подход к Django-thnonic (?), Но это означает, что логика представления была отброшена назад в представления, которые мне не нравятся.
Используйте тег expr для установки значений в шаблонах нижнего уровня. Примечание: это работает только в том случае, если вы {% include%} шаблон, потому что он должен быть оценен до включения. Вы не можете сделать это с помощью {% extends%}, потому что это должно быть первым в дочернем шаблоне.
Переключитесь на Jinja2, по крайней мере, для просмотров, где вам нужно это сделать.
После того, как вы установили эти значения, вы можете делать такие вещи:
<div class="foo{% if foo_active%}_active{%endif%}"> stuff </div>
Это делает класс div "foo", когда он неактивен, и "foo_active", когда он есть. Стиль по вкусу, но не добавляйте слишком много корицы.: -)
Я принял подход Jarret Hardie "low tech" в подобном, err... контексте (да, это каламбур... который не будет иметь для вас никакого смысла, если я не скажу вам, что я не занимался навигацией но установив цвет рамки кнопок, чтобы показать, какой из них был нажат).
Но моя версия немного компактнее, я думаю. Вместо того, чтобы определять только одну активную панель контекстной переменной в представлении, я возвращаю словарь, но всегда только с одной парой ключ-значение: например. activebar = {'foo': 'active'}.
Затем в шаблоне я просто пишу class= "{{activebar.foo}} в якоре foo и, соответственно, в других якорях. Если определено, что только activebar.foo имеет значение" active ", то activebar.bar в якоре бара ничего не сделает. Может быть," терпеть неудачу" - это правильная беседа с Django. И Боб твой дядя.
EDIT: Ой... прошло несколько дней, и хотя то, что я написал выше, работало для меня, проблема возникла, когда я ввел в навигатор якорь с новым окном в качестве цели. Это, по-видимому, было причиной странного сбоя: после нажатия на новое окно (вкладка в Firefox), а затем вернувшись к тому, с которого было запущено новое окно, части дисплея под навигационной панелью стали пустыми, когда я быстро перемещал курсор над элементами на навигационной панели --- не нажимая ни на что. Мне пришлось принудительно перерисовать экран, перемещая полосу прокрутки (не перезагружая страницу, хотя это слишком сработало, потому что оно связано с перерисовкой экрана).
Я слишком много нуба, чтобы понять, почему это может произойти. И возможно, что я сделал что-то еще, что вызвало проблему, которая каким-то образом ушла. Но... я нашел более простой подход, который отлично работает для меня. Мои обстоятельства заключаются в том, что каждый дочерний шаблон, который запускается из представления, должен приводить к тому, что связанный элемент навигатора должен отображаться как "активный". Действительно, этот элемент navbar - это тот, который запустил представление, которое запустило дочерний шаблон - обычное дело.
Мое решение --- давайте возьмем элемент навигации "login" в качестве примера --- это поместить его в дочерний шаблон, содержащий форму входа.
{% block login %}active{% endblock %}
Я поставил его ниже заголовка, но я не предполагаю, что это место имеет значение. Затем в родительском шаблоне, который содержит определение navbar, для тега li, который окружает якорь для элемента навигации navbar, я положил... ну вот код:
<li class="{% block login %}{% endblock %}"><a href="/mysite/login">Login</a></li>
Таким образом, когда дочерний шаблон визуализируется, родитель будет показывать элемент навигационной панели входа как активный, а Боб все еще ваш дядя.
Словарный подход, который я описал выше, заключался в том, чтобы показать, какая из кнопок кнопок была нажата, когда все они были на одном и том же дочернем шаблоне. Это все еще работает для меня, и поскольку задействован только один дочерний шаблон, я не вижу, как мой новый метод для navbars будет работать в этом случае. Обратите внимание, что при новом методе отображения navbars даже не задействованы. Simpler!
К сожалению, я не могу найти чистый способ.
Закончено помещать тег в каждое приложение base.html:
<span class="main_nav_bar_hint" id="2"></span>
(На самом деле я использую два. Один набор из базы приложений для основного навигатора. Один набор страниц приложения для панели навигации приложения)
И немного магии JQuery в проекте base.html
$(document).ready(function() { $("#nav_menu_" + $(".main_nav_bar_hint").attr("id")).removeClass("normal").addClass("selected"); })
Его немного взломать, но таким образом его легко понять, и мне нужно только сделать логические изменения, добавив еще приложения.