Наследование шаблонов нескольких уровней в Jinja2?

Я делаю html/css по профессии, и я работаю над проектами django в качестве дизайнера шаблонов. В настоящее время я работаю над сайтом, который использует Jinja2, который я использую около 2 недель. Я только что узнал, прочитав документацию, что Jinja2 не поддерживает наследование шаблонов нескольких уровней, так как вы не можете сделать больше одного

{% extends "foo" %}

за рендеринг. Теперь я уверен, что вы можете сделать это в Django, что является мощным, потому что вы можете указать базовый шаблон, указать на нем 3 или 4 шаблона, а затем построить мясо ваших страниц с помощью этих базовых шаблонов. Разве это не точка наследования, поэтому у вас больше возможностей для абстрактного, поэтому ваш единственный беспорядок с уникальным кодом?

В любом случае я понятия не имею, что здесь делать. Я не знаю, есть ли способ сделать это, что будет работать так же хорошо, как с шаблонами Django. Я не специалист в Django или Jinja (2), но я могу предоставить любую необходимую информацию.

Ответы

Ответ 1

Как написала документация, казалось, что он не поддерживает уровни наследования (n) глубоко.

В отличие от Python Jinja не поддерживает множественное наследование. Таким образом, вы можете есть один расширяет тег, называемый per рендеринга.

Я не знал, что это просто правило, говорящее, что 1 распространяется на шаблон... Теперь я знаю, с некоторой помощью от канала jinja irc.

Ответ 2

Один из лучших способов добиться множественного уровня шаблонов с помощью jinja2 - использовать 'include' скажем, у вас есть base_layout.html 'в качестве базового шаблона

<!DOCTYPE html>
<title>Base Layout</title>
<div>
  <h1>Base</h1>
  .... // write your code here
  {% block body %}{% endblock %}
</div>

а затем вы хотите иметь child_layout.html, который расширяет 'base_layout.

{% include "base_layout.html" %}
  <div>
  ... // write your code here
  </div>
{% block body %}{% endblock %}

и теперь ваша страница может просто расширять " child_layout.html", и она будет иметь как base_layout.html, так и child_layout.html

{% extends "child_layout.html" %}
{% block body %}
  ...// write your code here
{% endblock %}

Ответ 3

Недавно я столкнулся с той же проблемой. Я хотел наследовать несколько дочерних шаблонов, и это сработало. Чтобы проиллюстрировать это, я хотел бы показать вам решение, которое сработало для меня:

У меня был файл base.html с блочным контентом и расширен с помощью manage.html. и что manage.html имеет блок sub_manage, который расширяется через internet_market.html, поэтому визуально он выглядит так:

|- base.html (block content)
|--manage.html (extends base.html)
|---sub_manage.html (extends manage.html)

когда я его отобразил, everythink работал нормально, а это значит, что вы можете иметь несколько {% extends%} в одном рендере. единственное, что, если вы используете относительные ссылки на ваши файлы css или js, то это может не сработать, скорее оно будет отображать, но не найдет ваши файлы css/js. как:

<head>  
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="../static/css/bootstrap.min.css">
<script type="text/javascript" src="../static/js/bootstrap.min.js"></script>
<style type="text/css">
</head>

В этом случае вам нужно использовать динамические ссылки, используя url_for. как:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="{{url_for("static", filename = "css/bootstrap.min.css")}}">
<script type="text/javascript" src="{{url_for("static", filename = "js/bootstrap.min.js")}}"></script>
<style type="text/css">

Ответ 4

См. документацию расширение, включая и импорт.

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

Ответ 5

Попробуйте это, эта работа для меня благодаря ответу @Ixm.

base.html

<html xmlns="http://www.w3.org/1999/xhtml">
    <body>
      {% block content %}{% endblock %}
    </body>
</html>

content.html

{% extends "base.html" %}
{% block content %}
<table>
  <tr>
  {% include "footer.html" %}
  </tr>
</table>
{% endblock %}

footer.html

{% block footer %} <td> test</td>{% endblock %}

и вызов с помощью

env = Environment(loader=FileSystemLoader(os.path.join(path, "Layouts")))
template = env.get_template('content.html')
html = template.render()
print html

Ответ 6

Вы можете использовать следующий способ, чтобы объединить разное содержимое в один файл layout.html для различных макетов:

{% if instance == 'type1' %}

{% elif instance == 'type2' %}

{% else %}

{% endif %}

... и звоните:

render_template('layout', instance='%s' % instance)

в коде Python.