Jinja2中的多级模板继承?

时间:2009-12-29 20:03:42

标签: python css django django-templates jinja2

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

{% extends "foo" %}

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

无论如何我不知道该怎么做。我不知道是否有某些方法可以使用Django模板。我不是Django或Jinja(2)的专家,但我可以提供所需的任何信息。

8 个答案:

答案 0 :(得分:27)

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

  

与Python不同,Jinja不支持   多重继承。所以你只能   有一个扩展标记叫per   渲染。

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

答案 1 :(得分:20)

使用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 %}

答案 2 :(得分:4)

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

我有一个base.html文件,其中包含阻止内容并由manage.html扩展。 manage.html有一个block 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">

答案 3 :(得分:4)

试试这个,感谢@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

答案 4 :(得分:3)

请参阅文档extendingincludingimporting

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

答案 5 :(得分:1)

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

{% if instance == 'type1' %}

{% elif instance == 'type2' %}

{% else %}

{% endif %}

...并致电:

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

在python代码中。

答案 6 :(得分:0)

多重继承和多重继承是不同的。我了解这个问题与后者有关。

让我展示我的解决方法:

parent-template.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>

child-template.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使用子模板(导航栏)的数据。

答案 7 :(得分:-1)

经过长时间的努力,我发现jinja2模板中{{super}}具有多个继承级别。

以下内容受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(由于缩进,给出或使用一些空格字符)。