Подтвердить что ты не робот

Шаблоны Django: переопределение блоков включенных шаблонов для детей через расширенный шаблон

Мне интересно, знает ли кто, как справиться со следующей причудливой структурой шаблонов:

### base.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">

<head>
  <title> {% block title %} Title of the page {% endblock %} </title>
</head>

<body>
  <header>
    {% block header %}
      {% include "base/header.html" %}
    {% endblock header %}
  </header>
  {% block content %}{% endblock %}
</body>

</html>

### base/header.html
<div id="menu-bar">
  {% block nav %}
    {% include "base/nav.html" %}
  {% endblock %}
</div>

### base/nav.html
<nav id="menu">
  <ul>
    <li>
      <a href="/profile/">My Profile</a>
    </li>
    <li>
      <a href="/favs/">My Favorites</a>
    </li>
    {% block extra-content %}{% endblock %}
  </ul>
</nav>

И, в основе дела:


### app/somepage.html
{% extends "base.html" %}
{% block content %}
  <p>Content is overridden!</p>
{% endblock %}

{% block extra-content %}
  <p>This will not show up, though...</p>
{% endblock %}

{% block nav %}
  <p>Not even this.</p>
{% endblock %}

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

Я полагаю, я мог бы сделать base.html шелухой пустых неиспользуемых вложенных блоков, охватывающих все будущие непредвиденные ситуации, но может ли это отменить правильно? И это единственный способ?

Если вам интересно, почему у меня есть двунаправленный include/extends workflow вокруг base.html, у меня есть много подшаблонов, которые я хочу использовать во всем проекте: Заголовки, нижние колонтитулы, navs, боковые панели и т.д.. Все они будут состоять в структуре по всему сайту, но во многих случаях для целого подразделения сайта потребуются лишь некоторые из этих подшаблонов. Моя идея состояла в том, чтобы определить подшаблоны под папкой templates/base и иметь шаблоны /base -type1.html, templates/base-type2.html и т.д., Чтобы распространяться в других местах. Каждый тип будет ссылаться только на вспомогательные шаблоны и переопределять их для размещения контента по мере необходимости.

4b9b3361

Ответ 1

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

Ответ 2

Кажется малоизвестным, что вы можете использовать ключевое слово with с include для передачи переменных в контексте включенный шаблон - вы можете использовать его для указания включений в включенном шаблоне:

# base.html
<html>
    <body>
        {% block header %}{% include "header.html" %}{% endblock %}
    </body>
</html>

# header.html
# some stuff here
<div id="header">
    <img src="logo.png">
    {% include nav_tmpl|default:"navigation.html" %}
</div>

# special_page.html (uses other navigation)
{% extends "base.html" %}
{% block header %}
    {% include "header.html" with nav_tmpl="special_nav.html" %}
    # you might also want to wrap the include in an 'if' tag if you don't want anything
    # included here per default 
{% endblock %}

Этот подход сэкономит вам хотя бы один дополнительный файл только для перезаписи блока. Вы также можете использовать ключевое слово with для передачи значения через большую иерархию включений.

Ответ 3

Вариант террас для решения предложенный @Бернхардом Валлантом:

# base.html
<html>
    <body>
        {% block header %}{% include "header.html" %}{% endblock %}
    </body>
</html>

# header.html
# some stuff here
<div id="header">
    <img src="logo.png">
    {% include nav_tmpl|default:"navigation.html" %}
</div>

# special_page.html (uses other navigation)
{% extends "base.html" %}
{% block header %}
    {% with nav_tmpl="special_nav.html" %}
        {{ block.super }}
    {% endwith %}
{% endblock %}