从其他模板引擎切换

如果您在过去使用过不同的模板引擎,并且希望切换到jinja2,这里有一个小指南,其中显示了一些常见的、类似于python的文本模板引擎之间的基本语法和语义更改。

Jinja1

在API用法和模板语法方面,jinja2主要与jinja1兼容。下表解释了Jinja1和2之间的差异。

API

加载器

Jinja2使用不同的加载程序API。由于模板的内部表示形式已更改,因此不再支持外部缓存系统(如memcached)。现在模板消耗的内存与常规的Python模块相当,外部缓存没有任何优势。如果您以前使用过自定义加载程序,请看一下 loader API .

从字符串加载模板

在过去,通过使用 jinja.from_string . Jinja2提供了 Template 类,可用于执行相同的操作,但具有可选的附加配置。

自动Unicode转换

Jinja1执行了将给定编码中的字节串自动转换为Unicode对象的操作。此转换不再实现,因为它是不一致的,因为大多数库使用常规的python-ascii字节串到unicode转换。由Jinja2提供支持的应用程序 不得不 在任何地方内部使用unicode,或者确保jinja2只传递unicode字符串。

I18N

Jinja1使用定制翻译实现国际化。i18n现在作为jinja2扩展提供,使用一个更简单、更容易获取的界面,并支持babel。有关详细信息,请参阅 i18n扩展 .

内部方法

Jinja1在环境对象上暴露了一些内部方法,例如 call_functionget_attribute 以及其他。虽然它们被标记为内部方法,但可以重写它们。Jinja2没有同等的方法。

沙箱

默认情况下,jinja1正在运行沙盒模式。很少有应用程序实际使用该功能,因此它在Jinja2中成为可选的。有关沙盒执行的更多详细信息,请参阅 SandboxedEnvironment .

语境

Jinja1有一个堆叠的上下文作为传递给环境的变量的存储。在Jinja2中有一个类似的物体存在,但它不允许修改,也不允许单独存在。由于继承是动态的,因此在模板计算期间可能存在多个上下文对象。

过滤器和试验

过滤器和测试现在是常规功能。它不再是必需的,并且允许使用工厂功能。

模板

jinja2的语法与jinja1基本相同。不同的是,宏现在需要在参数列表周围加括号。

此外,jinja2现在允许动态继承,动态包含。旧助手函数 rendertemplate 消失了, include 可以改为使用。包括不再导入宏和变量分配,为此 import 输入 文档。

另一个小变化发生在 for -标签。特殊循环变量没有 parent 属性,而必须自己为循环命名。见 访问父循环 了解更多详细信息。

丹戈

如果您以前使用过django模板,您应该会发现jinja2非常熟悉。实际上,大多数语法元素的外观和工作方式都相同。

但是,jinja2提供了文档中涉及的更多语法元素,并且有些工作略有不同。

本节介绍模板更改。由于API本质上是不同的,我们在这里不讨论它。

方法调用

在Django方法中,隐式调用Work,而Jinja需要显式的Python语法。因此,德姜戈代码:

{% for page in user.get_created_pages %}
    ...
{% endfor %}

…在Jinja看起来像这样:

{% for page in user.get_created_pages() %}
    ...
{% endfor %}

这允许您将变量传递给方法,这在Django中是不可能的。此语法也用于宏。

筛选参数

Jinja2为过滤器提供了多个参数。参数传递的语法也不同。Django中的模板如下:

{{ items|join:", " }}

在Jinja2看起来是这样的:

{{ items|join(', ') }}

它有点冗长,但它允许不同类型的参数(包括变量)和多个参数。

测验

除了过滤器之外,还可以使用IS运算符执行测试。以下是一些例子:

{% if user.user_id is odd %}
    {{ user.username|e }} is odd
{% else %}
    hmm. {{ user.username|e }} looks pretty normal
{% endif %}

循环

for循环的工作方式与django非常相似,但值得注意的是,循环上下文的jinja2特殊变量被称为 loop 不是 forloop 就像在Django一样。

此外,Django empty 参数被调用 else 在Jinja2。例如,django模板:

{% for item in items %}
    {{ item }}
{% empty %}
    No items!
{% endfor %}

…在Jinja2看起来是这样:

{% for item in items %}
    {{ item }}
{% else %}
    No items!
{% endfor %}

循环

这个 {{% cycle %}} 标记在jinja2中不存在;但是,可以通过使用 cycle 循环上下文特殊变量上的方法。

以下Django模板:

{% for user in users %}
    <li class="{% cycle 'odd' 'even' %}">{{ user }}</li>
{% endfor %}

…在Jinja2看起来是这样:

{% for user in users %}
    <li class="{{ loop.cycle('odd', 'even') }}">{{ user }}</li>
{% endfor %}

没有等价的 {{% cycle ... as variable %}} .

鲭鲨

如果到目前为止您已经使用了Mako并希望切换到Jinja2,则可以将Jinja2配置为更像Mako:

env = Environment('<%', '%>', '${', '}', '<%doc>', '</%doc>', '%', '##')

在这样配置的环境下,jinja2应该能够解释mako模板的一小部分。Jinja2不支持嵌入的Python代码,因此您必须将其移出模板。defs(在jinja2中称为宏)和模板继承的语法也不同。以下Mako模板:

<%inherit file="layout.html" />
<%def name="title()">Page Title</%def>
<ul>
% for item in list:
    <li>${item}</li>
% endfor
</ul>

在Jinja2中的配置如下:

<% extends "layout.html" %>
<% block title %>Page Title<% endblock %>
<% block body %>
<ul>
% for item in list:
    <li>${item}</li>
% endfor
</ul>
<% endblock %>