从其他模板引擎切换 — Jinja 文档

来自菜鸟教程
Jinja/docs/3.0.x/switching
跳转至:导航、​搜索

从其他模板引擎切换

如果您过去使用过不同的模板引擎并想切换到 Jinja,这里有一个小指南,它展示了 Python 的一些常见的、相似的文本模板引擎之间的基本句法和语义变化。

金甲1

Jinja 2 在 API 使用和模板语法方面与 Jinja 1 基本兼容。 Jinja 1 和 2 之间的差异在以下列表中进行了解释。

应用程序接口

装载机
Jinja 2 使用不同的加载器 API。 由于模板的内部表示发生了变化,因此不再支持外部缓存系统,例如 memcached。 模板消耗的内存现在与常规 Python 模块相当,外部缓存没有任何优势。 如果您过去使用过自定义加载程序,请查看新的 加载程序 API
从字符串加载模板
过去,可以使用 jinja.from_string 从具有默认环境配置的字符串生成模板。 Jinja 2 提供了一个 Template 类,可用于执行相同的操作,但具有可选的附加配置。
自动unicode转换
Jinja 1 将给定编码中的字节自动转换为 unicode 对象。 由于大多数库都使用常规 Python ASCII 字节到 Unicode 转换,因此不再实现这种转换。 由 Jinja 2 驱动的应用程序必须 在内部到处使用 unicode 或确保 Jinja 2 只获取传递的 unicode 字符串。
国际化
Jinja 1 使用自定义翻译器进行国际化。 i18n 现在可作为 Jinja 2 扩展使用,并使用更简单、对 gettext 更友好的界面并支持 babel。 有关更多详细信息,请参阅 i18n 扩展
内部方法
Jinja 1 在环境对象上暴露了一些内部方法,例如 call_function、get_attribute 等。 虽然它们被标记为内部方法,但可以覆盖它们。 Jinja 2 没有等效的方法。
沙盒
Jinja 1 默认运行沙箱模式。 很少有应用程序实际使用该功能,因此它在 Jinja 2 中成为可选的。 有关沙盒执行的更多详细信息,请参阅 SandboxedEnvironment
语境
Jinja 1 有一个堆栈上下文作为传递给环境的变量的存储。 在 Jinja 2 中存在类似的对象,但它不允许修改,也不是单例。 由于继承是动态的,现在在模板评估期间可能存在多个上下文对象。
过滤器和测试
过滤器和测试现在是常规功能。 不再需要并允许使用工厂函数。


模板

Jinja 2 的语法与 Jinja 1 大致相同。 不同的是,宏现在需要在参数列表周围加上括号。

此外,Jinja 2 现在允许动态继承和动态包含。 旧的辅助函数 rendertemplate 现已消失,可以使用 include 代替。 不再包含导入宏和变量赋值,为此使用了新的 import 标签。 Import 文档中解释了这个概念。

for 标签中发生了另一个小变化。 特殊循环变量没有 parent 属性,您必须自己为循环设置别名。 有关更多详细信息,请参阅 访问父循环


姜戈

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

然而,Jinja 提供了一些文档中涵盖的更多语法元素,有些工作有点不同。

本节介绍模板更改。 由于 API 从根本上不同,我们不会在这里介绍。

方法调用

在 Django 中,方法调用是隐式的,而 Jinja 需要显式的 Python 语法。 因此这个 Django 代码:

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

...在 Jinja 中看起来像这样:

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

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


过滤参数

Jinja 为过滤器提供了不止一个参数。 参数传递的语法也不同。 在 Django 中看起来像这样的模板:

{{ items|join:", " }}

在 Jinja 中看起来像这样:

{{ 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 非常相似,但值得注意的是,循环上下文的 Jinja 特殊变量称为 loop,而不是 Django 中的 forloop。

此外,Django empty 参数在 Jinja 中称为 else。 例如,Django 模板:

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

...在 Jinja 中看起来像这样:

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

循环

Jinja 中不存在 {% cycle %} 标签; 但是,您可以通过对循环上下文特殊变量使用 cycle 方法来实现相同的输出。

以下 Django 模板:

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

...在 Jinja 中看起来像这样:

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

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


真子

如果您到目前为止已经使用过 Mako 并且想切换到 Jinja,您可以将 Jinja 配置为更像 Mako:

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

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

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

使用上述配置在 Jinja 中看起来像这样:

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