简体   繁体   English

Jinja2中的多级模板继承?

[英]Multiple level template inheritance in Jinja2?

I do html/css by trade, and I have been working on and off django projects as a template designer.我通过贸易来做 html/css,并且我一直在 django 项目中作为模板设计师工作。 I'm currently working on a site that uses Jinja2, which I have been using for about 2 weeks.我目前在一个使用 Jinja2 的网站上工作,我已经使用了大约 2 周。 I just found out through reading the documentation that Jinja2 doesn't support multiple level template inheritance, as in you can't do more than one我刚刚通过阅读文档发现 Jinja2 不支持多级模板继承,因为你不能做多个

{% extends "foo" %}

per rendering.每个渲染。 Now I'm pretty sure you can do this in Django, which is powerful because you can specify a base template, specify 3 or 4 templates based on that, and then build the meat of your pages using those base templates.现在我很确定你可以在 Django 中做到这一点,它很强大,因为你可以指定一个基本模板,基于它指定 3 或 4 个模板,然后使用这些基本模板构建页面的主体。 Isn't the point of inheritance so you have more power to abstract so your only really messing with unique code?不是继承的重点是让您有更多的抽象能力,所以您唯一真正弄乱了独特的代码吗?

In any case I have no idea what to do here.无论如何,我不知道在这里做什么。 I don't know if there is some way I can do it that will work as well as it could with the Django templates.我不知道是否有某种方法可以做到与 Django 模板一样好。 I'm not exactly an expert at either Django or Jinja(2) but I can provide any information needed.我不是 Django 或 Jinja(2) 的专家,但我可以提供任何需要的信息。

One of the best way to achieve multiple level of templating using jinja2 is to use 'include' let say you have ' base_layout.html ' as your base template使用 jinja2 实现多级模板的最佳方法之一是使用“include”,假设您将“ base_layout.html ”作为基本模板

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

and then you want to have ' child_layout.html ' that extends 'base_layout.然后你想拥有“child_layout.html”延伸“base_layout。

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

and now your page can just extends ' child_layout.html ' and it will have both base_layout.html and child_layout.html现在您的页面可以只扩展“ child_layout.html ”,它将同时具有base_layout.htmlchild_layout.html

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

The way the documentation worded it, it seemed like it didn't support inheritance (n) levels deep.文档的措辞方式,似乎它不支持继承 (n) 层深。

Unlike Python Jinja does not support multiple inheritance.不像 Python Jinja 不支持多重继承。 So you can only have one extends tag called per rendering.所以每次渲染只能调用一个 extends 标签。

I didn't know it was just a rule saying 1 extends per template.... I now know, with some help from the jinja irc channel.我不知道这只是一个规则,每个模板扩展 1 个......我现在知道了,在 jinja irc 频道的帮助下。

Try this, this work for me thanks to @Ixm answer.试试这个,感谢@Ixm 的回答,这对我有用。

base.html基本文件

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

content.html内容.html

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

footer.html页脚.html

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

and call with并打电话给

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

I recently faced the same issue.我最近遇到了同样的问题。 I wanted to inherit several child templates and it worked.我想继承几个子模板并且它起作用了。 To illustrate it I would like to show you a solution that worked for me:为了说明这一点,我想向您展示一个对我有用的解决方案:

I had a base.html file that has block content and extended by manage.html.我有一个包含块内容并由 manage.html 扩展的 base.html 文件。 and that manage.html has a block sub_manage which is extended by internet_market.html, so visually it looks like:并且 manage.html 有一个由 internet_market.html 扩展的块 sub_manage,因此在视觉上看起来像:

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

when I rendered it, everythink worked fine, which means that you can have several {% extends %} in one render.当我渲染它时,everythink 工作正常,这意味着您可以在一次渲染中拥有多个 {% extends %}。 the only thing is that if you are using relative links to your css or js files then it might not work, rather it will render, but it won't find your css/js files.唯一的问题是,如果您使用到 css 或 js 文件的相对链接,那么它可能不起作用,而是会呈现,但它不会找到您的 css/js 文件。 like:喜欢:

<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>

In that case you have to use dynamic links by using url_for.在这种情况下,您必须使用 url_for 来使用动态链接。 like:喜欢:

<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">

See the documentation extending , including , and importing .请参阅扩展包括导入文档。

This provides the means of getting functionality from multiple files for different purposes and is different from the depth of the nesting.这提供了为不同目的从多个文件获取功能的方法,并且与嵌套的深度不同。 You can perfectly have a template that extends a template that extends a template...您可以完美地拥有一个扩展模板的模板,该模板扩展了一个模板...

After struggling for a long time, I found {{super}} for multiple levels of inheritance in jinja2 templates.苦苦挣扎了半天,在jinja2模板中找到了多层次继承的{{super}}

The following is inspired from https://stackoverflow.com/a/31093830/1300775 .以下内容来自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 %}

Rendering template layer-2.html will output Brand - Section - Article (give or take a few spacing characters due to the indentation).渲染模板layer-2.html将输出Brand - Section - Article (由于缩进而给或取一些空格字符)。

You could use the following way to combine different contents into a single layout.html for various layout designs:您可以使用以下方式将不同的内容组合到一个 layout.html 中,用于各种布局设计:

{% if instance == 'type1' %}

{% elif instance == 'type2' %}

{% else %}

{% endif %}

...and call: ...并调用:

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

in python code.在python代码中。

Multiple inheritance and multiple-level inheritance are not the same.多重继承和多级继承是不一样的。 I understand the question is related to the latter.我理解这个问题与后者有关。

Let me show my workaround for the problem:让我展示我解决这个问题的方法:

parent-template.html父模板.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子模板.html

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

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

login.html (where I don't need navbar) login.html(我不需要导航栏)

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

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

home.html (where I need navbar) home.html(我需要导航栏的地方)

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

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

Both login.html and home.html uses all the data from parent-template, but only home.html uses data from child-template (the navbar). login.html 和 home.html 都使用来自父模板的所有数据,但只有 home.html 使用来自子模板(导航栏)的数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM