40

我做 html/css 的贸易,我一直在从事和关闭 django 项目作为模板设计师。我目前正在一个使用 Jinja2 的网站上工作,我已经使用了大约 2 周。我刚刚通过阅读文档发现 Jinja2 不支持多级模板继承,因为你不能做多个

{% extends "foo" %}

每个渲染。现在我很确定你可以在 Django 中做到这一点,它很强大,因为你可以指定一个基本模板,在此基础上指定 3 或 4 个模板,然后使用这些基本模板构建你的页面。继承的重点不是让你有更多的抽象能力,所以你唯一真正弄乱了独特的代码吗?

无论如何,我不知道在这里做什么。我不知道是否有某种方法可以像使用 Django 模板一样工作。我不是 Django 或 Jinja(2) 方面的专家,但我可以提供任何需要的信息。

4

8 回答 8

40

使用 jinja2 实现多级模板的最佳方法之一是使用“包含”假设您有“ base_layout.html ”作为基本模板

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

然后你想拥有扩展' base_layout.html '的'child_layout.html'。

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

现在您的页面可以扩展“ child_layout.html ”,它将同时具有base_layout.htmlchild_layout.html

{% extends "child_layout.html" %}
{% block body %}
  ...// write your code here
{% endblock %}
于 2013-05-22T07:05:33.617 回答
33

文档的措辞方式似乎不支持深度继承(n)级别。

不像 Python Jinja 不支持多重继承。因此,每次渲染只能调用一个扩展标签。

我不知道这只是一个规则说每个模板扩展 1.... 我现在知道了,在 jinja irc 频道的帮助下。

于 2009-12-30T01:05:53.203 回答
15

试试这个,感谢@Ixm的回答,这对我有用。

base.html

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

内容.html

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

页脚.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
于 2015-11-06T20:34:05.283 回答
4

我最近遇到了同样的问题。我想继承几个子模板并且它起作用了。为了说明这一点,我想向您展示一个对我有用的解决方案:

我有一个包含块内容并由 manage.html 扩展的 base.html 文件。并且 manage.html 有一个由 internet_market.html 扩展的块 sub_manage,所以在视觉上它看起来像:

|- 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">
于 2014-07-08T15:29:34.153 回答
3

请参阅扩展包含导入的文档。

这提供了为不同目的从多个文件中获取功能的方法,并且不同于嵌套的深度。您可以完美地拥有一个扩展模板的模板,该模板扩展模板......

于 2014-06-02T16:06:44.497 回答
3

折腾了半天,找到{{super}}了jinja2模板中的多级继承。

以下内容来自https://stackoverflow.com/a/31093830/1300775的启发。

base.html

<html>
<body>
  {% block title %}
    Brand
  {% endblock %}
</body>

layer-1.html

  {% extends "base.html" %}
  {% block title %}
    {{ super() }} - Section
  {% endblock %}

layer-2.html

  {% extends "layer-1.html" %}
  {% block title %}
    {{ super() }} - Article
  {% endblock %}

渲染模板layer-2.html将输出Brand - Section - Article(由于缩进而给出或采用一些间距字符)。

于 2020-04-19T12:58:09.647 回答
1

您可以使用以下方式将不同的内容组合成一个 layout.html 用于各种布局设计:

{% if instance == 'type1' %}

{% elif instance == 'type2' %}

{% else %}

{% endif %}

...并致电:

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

在python代码中。

于 2019-01-21T20:17:35.843 回答
1

多重继承和多级继承是不一样的。我知道这个问题与后者有关。

让我展示我的解决方法:

父模板.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset='utf-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <title>Your Title</title>
    <link rel='stylesheet' href="{{ url_for('static', filename='css/main.css') }}">
    {% block head %}{% endblock %}
</head>

<body>
    {% block nav %}{% endblock %}
    {% block body %}{% endblock %}
</body>

</html>

子模板.html

{% extends 'parent-template.html' %}

{% block nav %}
<header>
    <div>
        <nav>
            ...
            [navbar html code]
            ...
        </nav>
    </div>
</header>
{% endblock %}

login.html(我不需要导航栏)

{% extends 'parent-template.html' %}

{% block body %}
<header>
    ...
    [header html code]
    ...
</header>
<main>
    ...
    [main html code]
    ...
</main>
{% endblock %}

home.html(我需要导航栏的地方)

{% extends 'child-template.html' %}

{% block body %}
<main>
    ...
    [main html code]
    ...
</main>
{% endblock %}

login.html 和 home.html 都使用父模板中的所有数据,但只有 home.html 使用子模板(导航栏)中的数据。

于 2020-07-02T19:12:51.380 回答