Ответ 1
Вы можете решить эту проблему, расширив ваши включенные в настоящее время шаблоны, а затем добавив расширение вместо текущего шаблона базы.
Мне интересно, знает ли кто, как справиться со следующей причудливой структурой шаблонов:
### 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 и т.д., Чтобы распространяться в других местах. Каждый тип будет ссылаться только на вспомогательные шаблоны и переопределять их для размещения контента по мере необходимости.
Вы можете решить эту проблему, расширив ваши включенные в настоящее время шаблоны, а затем добавив расширение вместо текущего шаблона базы.
Кажется малоизвестным, что вы можете использовать ключевое слово 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
для передачи значения через большую иерархию включений.
Вариант террас для решения предложенный @Бернхардом Валлантом:
# 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 %}