在Jinja2中,如何将宏与块标记结合使用?

时间:2022-01-06 00:25:46

I'm a front end developer, and I've been trying to get a hang on using Jinja2 effectively. I want to tweak a current site so it has multiple base templates using inheritance, it fully uses block tags to substitute content and override it, and uses macros to support passing of arguments.

我是一个前端开发人员,我一直在尝试有效地使用Jinja2。我想对当前站点进行调整,使其具有使用继承的多个基本模板,它完全使用块标记替换内容并覆盖它,并使用宏来支持参数的传递。

My base template contains this code (edited for simplicity):

我的基本模板包含以下代码(为简单起见而编辑):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
{% from "foo.html" import macro1, macro2, macro3 %}
{% macro base_template(title=none, arg2=none, urls={}, arg3=false) %}
<html>
  <title>{{ title }} | Site.com</title>
  ....
  {{ caller() }}
  ....
</html>
{% endmacro %}

{% block content %}{% endblock %}

And my pages that extend it look like this:

我的页面看起来是这样的:

{% extends "base.html" %}
{% block content %}
{% call base_template(title="home", arg2="active", arg3="true") %}
(html code here)
{% endcall %}
{% endblock %}

So basically all the pages extend base, they call a macro and pass arguments to that macro. I don't quite understand it all, but the main point is that this allows default values and a degree of flexibility that doesn't require redefining an entire block: it gives some degree of flexibility and power. Again this is heavily simplified.

基本上所有的页面都扩展了基,它们调用一个宏并将参数传递给这个宏。我不是很理解,但主要的一点是,它允许默认值和一定程度的灵活性,不需要重新定义整个块:它提供一定程度的灵活性和力量。这是非常简化的。

The only problem is, this negates my ability to use blocks. Macros are for flexibility, but with blocks, I have the ability to override something entirely, or use it's parents contents and add to it, which I can't do with Macros (at least I don't think). The problem is, I can't wrap things in blocks, else they won't see the values in the macro. For instance, doing this:

唯一的问题是,这否定了我使用块的能力。宏用于灵活性,但是对于块,我可以完全覆盖某些内容,或者使用它的父内容并添加到其中,这是我不能使用宏的(至少我不这么认为)。问题是,我不能把东西打包成块,否则它们在宏中看不到值。例如,这样做:

{% block title %}<title>{{ title }} | Site.com</title>{% endblock %}

Will fail because it will say title is undefined.

会失败,因为它会说标题是未定义的。

Ultimately I am looking for a way to utilize both the power and organiztional aspects of blocks, but still be able to utilize the logic & terseness of macros. If anyone could give me any help as to how I might go about this problem, I would really appreciate it.

最后,我正在寻找一种既能利用块的力量又能利用块的组织性的方法,但仍然能够利用宏的逻辑和简洁性。如果有人能帮助我解决这个问题,我将不胜感激。

1 个解决方案

#1


20  

Blocks are only definable at a template's top level. If you extend a template, any values set in the child template using a set tag will be accessible from the template it is extending. For example, if you have a template named layout.html:

块只能在模板的顶层定义。如果您扩展了一个模板,那么使用set标记的子模板中的任何值都可以从它所扩展的模板中访问。例如,如果您有一个名为layout.html的模板:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
  <title>{{ title }} | Site.com</title>
  ....
  {% block content %}{% endblock content %}
  ....
</html>

And you have this child template, index.html:

你有这个子模板,index。html:

{% extends "layout.html" %}
{% set title = 'Homepage' %}
{% block content %}
(html code here)
{% endblock content %}

Then the reference to title in the parent would resolve to 'Homepage'. You can do this with any type of variable. For what you're doing, I don't think there is any need for macros - if you take advantage of this feature and place blocks well, you will be able to do pretty much everything you need to do as far as layouts are concerned. I would look at some of the templates used by Plurk Solace, which is written by one of the Jinja2 authors, if you want to get a good idea of when to use various features of Jinja2.

然后,在父类中对标题的引用将解析为“主页”。你可以用任何类型的变量来做。对于您正在做的事情,我认为没有必要对宏——如果您充分利用了这个特性,并且将块放置好,那么在布局方面,您将能够做几乎所有您需要做的事情。如果您想了解什么时候使用Jinja2的各种特性,我将查看Plurk Solace的一些模板,它们是由Jinja2的一位作者编写的。

#1


20  

Blocks are only definable at a template's top level. If you extend a template, any values set in the child template using a set tag will be accessible from the template it is extending. For example, if you have a template named layout.html:

块只能在模板的顶层定义。如果您扩展了一个模板,那么使用set标记的子模板中的任何值都可以从它所扩展的模板中访问。例如,如果您有一个名为layout.html的模板:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
  <title>{{ title }} | Site.com</title>
  ....
  {% block content %}{% endblock content %}
  ....
</html>

And you have this child template, index.html:

你有这个子模板,index。html:

{% extends "layout.html" %}
{% set title = 'Homepage' %}
{% block content %}
(html code here)
{% endblock content %}

Then the reference to title in the parent would resolve to 'Homepage'. You can do this with any type of variable. For what you're doing, I don't think there is any need for macros - if you take advantage of this feature and place blocks well, you will be able to do pretty much everything you need to do as far as layouts are concerned. I would look at some of the templates used by Plurk Solace, which is written by one of the Jinja2 authors, if you want to get a good idea of when to use various features of Jinja2.

然后,在父类中对标题的引用将解析为“主页”。你可以用任何类型的变量来做。对于您正在做的事情,我认为没有必要对宏——如果您充分利用了这个特性,并且将块放置好,那么在布局方面,您将能够做几乎所有您需要做的事情。如果您想了解什么时候使用Jinja2的各种特性,我将查看Plurk Solace的一些模板,它们是由Jinja2的一位作者编写的。