django: использование блоков во включенных шаблонах - PullRequest
33 голосов
/ 09 марта 2012

У меня есть некоторые html-структуры, которые многократно используются в разных местах.Он отличается от общего шаблона, поэтому я не могу его расширить, его также можно использовать для содержания сложного содержимого, поэтому я не думаю, что определение его в качестве тега шаблона делает хорошую работу.Ниже приведен некоторый псевдокод , описывающий мой желаемый результат, при использовании template_level2.html вы можете легко поместить материал в reusable_pattern_template, вызвав блок внутри него.Если я использую этот код, то, что вы пишете в «фактическом содержании» template_level_2.html, не будет отображаться.Как мне с этим бороться?

base.html

<html>
<head></head>
<body>
{% block content %}{% endblock %}
</body>
</html>

template_level1.html

{% extends 'base.html' %}
{% block content %}
  Something here...
  {% include 'reusable_pattern_template.html' %}
  Something else here...
{% endblock %}

reusable_pattern_template.html

<div>
  <div>
    <div>
      {% block local_content %}{% endblock %}
    </div>
   </div>
</div>

template_level2.html

{% extends 'template_level1.html' %}
{% block local_content %}
  Actual content here...
{% endblock %}

обновление: Извините, у расширений в template_level2.html есть некоторая ошибка, я только что исправил ее.

Возможно, это не очень понятно, но приведенный выше код болеепсевдокода, описывающего мой желаемый результат.Короче говоря,

  • Я бы хотел включить в свои шаблоны небольшие фрагменты многократно используемых шаблонов HTML.
  • Эти шаблоны похожи на блоки, в которые можно помещать целые фрагменты содержимого HTML.,Так что контекстные переменные могут быть слишком ограничены для моей цели

Ответы [ 4 ]

48 голосов
/ 09 марта 2012

Django не обрабатывает блоки во включенных файлах.

Тег include должен рассматриваться как реализация «рендеринга этого подшаблона и включения HTML», а не как «разбора этого подшаблона и включения егосодержимое, как если бы оно было частью родителя ".Это означает, что между включенными шаблонами нет общего состояния - каждое включение является полностью независимым процессом рендеринга.( документация по тегу шаблона Django )

3 голосов
/ 10 марта 2012

Кажется, что последний шаблон пытается расширить себя (если он был в кавычках) .

Тебе действительно не нужно много сложности. На самом деле все гораздо проще.

Базовый шаблон должен содержать каркас вашего шаблона, после чего вы можете расширить его для выполнения настроек. Для многократно используемых блоков кода, которые вы не хотите включать в каждое ваше представление, include их, где это необходимо, но не используйте операторы block, extends или include во включенном файле. Django не будет их анализировать, но context variable, переданный из представления, все еще может быть использован.

2 голосов
/ 29 января 2018

Я столкнулся с этой проблемой и в итоге получил следующий компромисс, надеясь, что кто-то еще может найти его полезным. Он использует блоки with в дочерних шаблонах.

base.html хочет повторно использовать обычное nav.html include, но определяет некоторые блоки, в которых переменные внутри nav.html могут быть переопределены дочерними шаблонами .

<!-- base.html: -->
<html>
  [...]
  <nav class="desktop">
    {% block desktop_nav %}
      {% include "includes/nav.html" %}
    {% endblock %}
  </nav>
  [...]
  <nav class="mobile">
    {% block mobile_nav %}
      {% include "includes/nav.html" %}
    {% endblock %}
  </nav>
  [...]

Шаблон включения зависит от переменной с именем selected, которую base.html по умолчанию не определяет:

<!--includes/nav.html:-->
<a href="/about/" class="{% if selected == 'about' %}selected{% endif %}">About</a>
<a href="/people/" class="{% if selected == 'people' %}selected{% endif %}">People</a>
<a href="/contact/" class="{% if selected == 'contact' %}selected{% endif %}">Contact</a>

Но дочерние страницы могут переопределять это значение следующим образом:

<!--about.html:-->
{% extends "base.html" %}
{% block desktop_nav %}{% with selected='about' %}{{ block.super }}{% endwith %}{% endblock %}
{% block mobile_nav %}{% with selected='about' %}{{ block.super }}{% endwith %}{% endblock %}

так что, не идеально, мне все еще нужно иметь два отдельных блока и использовать эти блоки with дважды, но это позволяет мне переопределять переменные в include блоках из родительского шаблона.

0 голосов
/ 05 октября 2017

Вы можете разделить reusable_pattern_template на начальный и конечный шаблоны. Затем на уровне 1 вы можете включить включить начало, заблокировать, включить конец.

В качестве альтернативы вы можете передать имя шаблона в reusable_pattern_template в качестве переменной контекста и затем включить его в reusable_pattern_template. Это потребует изменения отношения между level1 и level2 в вашем примере, но в целом оно более мощное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...