Jinja2 中的多级模板继承?

发布于 2024-08-16 04:28:11 字数 410 浏览 10 评论 0原文

我以 html/css 为职业,并且一直作为模板设计师参与 django 项目。我目前正在开发一个使用 Jinja2 的网站,我已经使用它大约两周了。我刚刚通过阅读文档发现 Jinja2 不支持多级模板继承,因为每次渲染不能执行多个模板继承

{% extends "foo" %}

。现在我非常确定您可以在 Django 中执行此操作,Django 非常强大,因为您可以指定一个基本模板,基于该模板指定 3 或 4 个模板,然后使用这些基本模板构建页面的主要内容。难道继承的意义不是让你有更多的能力进行抽象,这样你就只能真正搞乱独特的代码吗?

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

I do html/css by trade, and I have been working on and off django projects as a template designer. I'm currently working on a site that uses Jinja2, which I have been using for about 2 weeks. 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

{% 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. 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. I'm not exactly an expert at either Django or Jinja(2) but I can provide any information needed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

窝囊感情。 2024-08-23 04:28:11

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

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

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

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

{% extends "child_layout.html" %}
{% block body %}
  ...// write your code here
{% endblock %}
孤城病女 2024-08-23 04:28:11

从文档的措辞来看,它似乎不支持深度继承 (n) 层。

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

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

The way the documentation worded it, it seemed like it didn't support inheritance (n) levels deep.

Unlike Python Jinja does not support
multiple inheritance. So you can only
have one extends tag called per
rendering.

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.

趴在窗边数星星i 2024-08-23 04:28:11

试试这个,这对我有用,感谢@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

Try this, this work for me thanks to @Ixm answer.

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

and call with

env = Environment(loader=FileSystemLoader(os.path.join(path, "Layouts")))
template = env.get_template('content.html')
html = template.render()
print html
爱已欠费 2024-08-23 04:28:11

经过一番苦苦挣扎,我在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 将输出标题块中的品牌 - 部分 - 文章

After struggling for a long time, I found {{super}} for multiple levels of inheritance in jinja2 templates.

The following is inspired from 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 in block title.

昵称有卵用 2024-08-23 04:28:11

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

我有一个包含块内容并由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">

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. and that manage.html has a block sub_manage which is extended by internet_market.html, so visually it looks like:

|- 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. 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.
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. 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">
残月升风 2024-08-23 04:28:11

请参阅文档扩展包括导入

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

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

小鸟爱天空丶 2024-08-23 04:28:11

多重继承和多级继承并不相同。我知道这个问题与后者有关。

让我展示一下我的问题解决方法:

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

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

<!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 (where I don't need navbar)

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

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

home.html (where I need navbar)

{% 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).

梦幻之岛 2024-08-23 04:28:11

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

{% if instance == 'type1' %}

{% elif instance == 'type2' %}

{% else %}

{% endif %}

调用: 。

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

...并在python代码中

You could use the following way to combine different contents into a single layout.html for various layout designs:

{% if instance == 'type1' %}

{% elif instance == 'type2' %}

{% else %}

{% endif %}

...and call:

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

in python code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文