Django: вложенные блоки с тем же именем - PullRequest
2 голосов
/ 21 июня 2011

Есть ли способ иметь блоки с одинаковым именем?

base.html:

Это шаблон с основным макетом.

<html>

  ...

  {% block content %}

  {% endblock %}

  ...

</html>

base_side_left.html:

Это шаблон с основным макетом + боковой панелью слева.

{% extends 'base.html' %}

{% block content %}

  <div class='sidebar'>
  </div>

  {% block content %}

    //This doesn't work because you can't have blocks with the same name//

  {% endblock %}

{% endblock

У меня есть несколько причин, почему я спрашиваю это:

  1. Легко изменить родительский элемент страницы без необходимости изменять имя блоков содержимого.
  2. Мне не нужно придумывать названия для моих блоков. Как контент-контент, боковая панель-контент и т. Д.

У меня есть два решения для этого, которые мне не нравятся, потому что они не СУХИЕ:

  1. Сделайте боковую панель частичной и включите ее в нужные вам шаблоны.
  2. Добавьте все в базовый шаблон и перезапишите те блоки, которые вам не нужны.

Если это невозможно с Django Template, могу ли я сделать что-то подобное с другим движком шаблонов?

Небольшое обновление:

template diagram

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

1 Ответ

6 голосов
/ 21 июня 2011

Нет, вы не можете. Из документов Django о наследовании шаблонов :

вы не можете определить несколько {% block %} тегов с одинаковыми именами в одном шаблоне. Это ограничение существует, потому что тег блока работает в «обоих» направлениях. То есть тег блока не только обеспечивает отверстие для заполнения - он также определяет содержимое, заполняющее отверстие в parent . Если бы в шаблоне было два тега {% block %} с одинаковыми именами, родитель этого шаблона не знал бы, какой из блоков использовать.

Мне не ясно, почему вы хотите это сделать.

Легко изменить родительский элемент страницы без необходимости менять имя блоков содержимого.

Существует только один тег {% block %} с заданным именем, а также только один тег {% extends %}. Я не вижу разницы в сложности.

Мне не нужно придумывать названия для моих блоков. Как контент-контент, боковая панель-контент и т. Д.

Любой, обслуживающий ваш код, быстро потеряет учет того, какой блок content эффективен, и запутается. Кроме того, имена должны иметь отношение к тому, что должен делать {% block %}. Поэтому мне интересно, почему у вас есть два шаблона, один, включая другой, с одинаковыми блоками.

Еще один пункт из документов :

Если вы обнаружите, что дублируете контент в нескольких шаблонах, это, вероятно, означает, что вы должны переместить этот контент в {% block%} в родительском шаблоне.

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

Это тоже может быть полезно:

Если вам нужно получить содержимое блока из родительского шаблона, переменная {{ block.super }} поможет. Это полезно, если вы хотите добавить содержимое родительского блока вместо того, чтобы полностью переопределить его. Данные, вставленные с помощью {{ block.super }}, не будут автоматически экранированы (см. Следующий раздел), поскольку они уже были экранированы, если необходимо, в родительском шаблоне.

Из того, что я могу сказать, это, вероятно, ваш лучший выбор:

Сделайте боковую панель частичной и включите ее в нужные вам шаблоны.

Как это не СУХОЙ? Вы должны повторить тег {% include %}?

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

РЕДАКТИРОВАТЬ: Глядя на ваш пример, вы можете сделать все это с помощью одного шаблона. CSS позаботится о вас здесь.

page_template.html:

<!DOCTYPE html PUBLIC -- ... -->
<html>
<head>
    <!-- ... other header fields ... -->
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <base href="{{ host }}{{ root }}{{ path }}" />
    <title>{% block title %}Untitled{% endblock %}</title>
    <link rel="icon" type="image/png"
        href="{{ root }}static/images/favicon.png" />
    <link rel="stylesheet" type="text/css"
        href="{{ root }}static/css/general.css" />
    <!-- other header fields here -->
{% block head %}{% endblock %}
</head>
<body class="{% block page_class %}no_sidebar{% endblock %}">
    <div id="page_header">
        <!-- page heading here -->
    </div>
    <div id="sidebar">
        {% block sidebar %}<!-- default sidebar here -->{% endblock %}
    </div>
    <div id="banner">
        {% block banner %}{% endblock %}
    </div>
    <div id="content">
        {% block content %}{% endblock %}
    </div>
</body>
</html>

general.css:

body.no_sidebar div#sidebar,
div#banner
{
    display: none;
}

div#sidebar
{
    width: 20%;
}

body.with_sidebar div#sidebar
{
    float: left;
}

body.with_banner div#banner
{
    display: block;
}

body.right_sidebar div#sidebar
{
    float: right;
}

Тогда ваши страницы выглядят так, в порядке ваших примеров:

plain_old_page.html:

{% extends base.html %}

{% block content %}
    <!-- content goes here -->
{% endblock %}

page_with_left_sidebar.html:

{% extends base.html %}
{% block page_class %}with_sidebar{% endblock %}

{% block sidebar %}
    <!-- sidebar goes here, if different from default -->
    <!-- otherwise omit this section -->
{% endblock %}

{% block content %}
    <!-- content goes here -->
{% endblock %}

page_with_left_sidebar_and_banner.html:

{% extends base.html %}
{% block page_class %}with_sidebar with_banner{% endblock %}

{% block sidebar %}
    <!-- sidebar goes here, if different from default -->
    <!-- otherwise omit this section -->
{% endblock %}

{% block banner %}
    <!-- banner goes here -->
{% endblock %}

{% block content %}
    <!-- content goes here -->
{% endblock %}

page_with_right_sidebar.html:

{% extends base.html %}
{% block page_class %}right_sidebar{% endblock %}

{% block sidebar %}
    <!-- sidebar goes here, if different from default -->
    <!-- otherwise omit this section -->
{% endblock %}

{% block content %}
    <!-- content goes here -->
{% endblock %}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...