Я хочу использовать один и тот же {% block%} дважды в одном шаблоне django. Я хочу, чтобы этот блок появлялся в моем базовом шаблоне более одного раза:
# base.html
<html>
<head>
<title>{% block title %}My Cool Website{% endblock %}</title>
</head>
<body>
<h1>{% block title %}My Cool Website{% endblock %}</h1>
</body>
</html>
А затем расширите его:
# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}
# pictures.html
{% extends 'base.html' %}
{% block title %}My Pictures{% endblock %}
# cats.html
{% extends 'base.html' %}
{% block title %}My Cats{% endblock %}
Я получу исключение, так как Django хочет, чтобы блок появлялся только один раз:
TemplateSyntaxError в /
Тег 'block' с именем 'title' встречается более одного раза
Быстрое и грязное решение - дублировать заголовок блока в title1 и title2 :
# blog.html
{% extends 'base.html' %}
{% block title1 %}My Blog{% endblock %}
{% block title2 %}My Blog{% endblock %}
Но это нарушение принципа DRY . Это было бы очень сложно, так как у меня много наследующих шаблонов, а также потому, что я не хочу идти к черту ;-)
Есть ли какой-нибудь трюк или способ решения этой проблемы? Как я могу повторить один и тот же блок в моем шаблоне, не дублируя весь код?
django
django-templates
dry
Дэвид Аркос
источник
источник
Ответы:
Я считаю, что использование контекстного процессора в этом случае является излишним. Вы легко можете это сделать:
а потом:
и так далее ... Похоже, DRY-совместимый.
источник
h1
содержимого внутри блока, который определяетtitle
. Или блок , который определяет часть изtitle
.Используйте плагин макросов шаблонов Django:
https://gist.github.com/1715202 (django> = 1.4)
или
http://www.djangosnippets.org/snippets/363/ (django <1.4)
django> = 1.4
и
django <1.4
и
источник
Вероятно, вы на самом деле не хотите использовать блок, а просто использовать переменную:
Затем вы устанавливаете заголовок через контекст.
источник
Вот способ, который я обнаружил, пытаясь сделать то же самое сам:
К сожалению, требуется дополнительный файл, но не требует передачи заголовка из представления.
источник
<tr>
ряд был довольно сложным.вы можете использовать
{% include subtemplate.html %}
более одного раза. это не то же самое, что блоки, но помогает.источник
include
это медленнее, чемblock
. docs.djangoproject.com/en/1.10/topics/performance/…Здесь есть обсуждение: http://code.djangoproject.com/ticket/4529 Очевидно, основная команда django отклоняет этот билет, потому что они думают, что это не часто используемый сценарий, однако я не согласен.
Блок повторения - простая и понятная реализация для этого: https://github.com/SmileyChris/django-repeatblock
макросы шаблона - еще один, однако автор упомянул, что он не был тщательно протестирован: http://www.djangosnippets.org/snippets/363/
Я использовал Repeatblock.
источник
В качестве обновления для всех, кто сталкивается с этим, я взял упомянутый выше фрагмент и превратил его в библиотеку тегов шаблонов, django-macros, которая делает макросы более мощными, а также явно реализует повторяющийся шаблон блока: django-macros .
источник
Вот легкое решение, подобное приведенному выше,
do_set
иdo_get
ответ на шаблонный тег. Django позволяет передавать весь контекст шаблона в тег, который позволяет определять глобальную переменную.base.html:
page.html:
пользовательский тег (идея здесь: https://stackoverflow.com/a/33564990/2747924 ):
Также не забывайте
{% load %}
настраиваемые теги или добавляйте их в список встроенных опций шаблона, чтобы вам не приходилось загружать их в каждый шаблон. Единственным ограничением этого подхода является{% define %}
необходимость вызова из тега блока, потому что дочерние шаблоны отображают только теги блока, соответствующие родительским тегам. Не уверен, есть ли способ обойти это. Также убедитесь, чтоdefine
звонок поступает, прежде чем вы попытаетесь его явно использовать.источник
Основываясь на предложении Ван Гейла, вы можете создавать теги get и set, добавив следующее в свой файл templatetags.py:
Затем установите значения в одном шаблоне через
{% set foo %}put data here{% endset %}
и получите их через{% get foo %}
другой.источник
Я тоже столкнулся с такой же потребностью в повторяющемся {% block%} в моих файлах шаблонов. Проблема в том, что я хочу, чтобы Django {% block%} использовался в любом случае условного выражения Django, и я хочу, чтобы {% block%} был перезаписан последующими файлами, которые могут расширить текущий файл. (Итак, в этом случае я определенно хочу больше блока, чем переменной, потому что я технически не использую его повторно, он просто появляется на любом конце условного выражения.
Эта проблема:
Следующий код шаблона Django приведет к ошибке синтаксиса шаблона, но я думаю, что это действительное «желание», чтобы определенный {% block%} повторно использовался в условном (IE, почему синтаксис синтаксиса Django проверяет синтаксис на ОБЕИХ концах условного оператора, разве он не должен проверять только условие ИСТИНА?)
Решение:
Вы можете использовать {% include%}, чтобы условно вставить {% block%} более одного раза. Это сработало для меня, потому что средство проверки синтаксиса Django включает только TRUTHY {% include%}. Смотрите результат ниже:
источник
Я использую этот ответ, чтобы вещи оставались сухими.
источник
Для этого есть два простых решения.
Самый простой - поместить заголовок в контекстную переменную. Вы должны установить переменную контекста в своем представлении.
Если вы используете что-то вроде общих представлений и у вас нет views.py для изображений, кошек и т. Д., Вы можете использовать собственный тег шаблона, который устанавливает переменную в контексте .
Переход по этому маршруту позволит вам сделать что-то вроде:
Затем в вашем base.html:
источник
Any variable set in the context will only be available in the same block of the template in which it was assigned. This behavior is intentional; it provides a scope for variables so that they don’t conflict with context in other blocks.
Выбранный ответ ссылается на простой обходной путь - обернуть один тег внутри другого в дочернем шаблоне, чтобы присвоить им одинаковое значение. Я использую это для таких изображений в социальных сетях.
Дочерний шаблон:
Затем в родительском
base.html
:источник
В веточке вы можете сделать это так:
источник