从其它模板引擎切换过来¶
如果你过去使用过不同的模板引擎,并且想切换到 Jinja,这里是一个小指南,它显示 Python 常见且类似的几个文本模板引擎之间的基本句法和语义变化。
Jinja 1¶
在 API 使用和模板语法方面,Jinja 2 与 Jinja 1 基本兼容。 以下列表解释 Jinja 1 和 2 之间的差异。
API¶
- Loaders
Jinja 2 使用不同的加载程序 API。 由于模板的内部表示形式已更改,因此不再支持外部缓存系统,如 memcached。 模板消耗的内存现在可与常规 Python 模块相媲美,外部缓存不会带来任何优势。 如果你过去使用过自定义加载程序,请查看新的加载程序 API。
- 从字符串加载模板
过去,可以使用jinja.from_string从具有默认环境配置的字符串生成模板。 Jinja 2 提供了一个
Template
类,可用于执行相同的操作,但具有可选的附加配置。- unicode 自动转换
Jinja 1 将给定编码的字节串自动转换为 unicode 对象。 这种此转换不再实现,因为它与大多数库都使用常规的 Python ASCII 字节串到 Unicode 的转换不一致。 由 Jinja 2 提供支持的应用程序必须 在任何地方使用 unicode,或者确保仅传递 unicode 字符串给 Jinja 2 。
- i18n
Jinja 1 使用自定义翻译程序进行国际化。 i18n 现在可作为Jinja 2扩展程序使用,并使用更简单、更易于获取文本的界面,并支持babel。 有关详细信息,请参阅i18n 扩展。
- 内部方法
Jinja 1 公开了环境对象的一些内部方法,例如call_function、get_attribute 等。 虽然它们被标记为内部方法,但可以重写它们。 Jinja 2 没有等效的方法。
- 沙盒
Jinja 1 默认运行沙盒模式。 很少有应用程序实际使用该功能,因此在 Jinja 2 中成为可选功能。 有关沙盒执行的更多详细信息,请参阅
SandboxedEnvironment
。- 上下文
Jinja 1 具有一个栈式的上下文,用于存储传递到环境的变量。 在 Jinja 2 中,存在一个类似的对象,但是它不允许修改,也不是单例。 由于继承是动态的,因此在模板评估期间可能存在多个上下文对象。
- 过滤器和测试
筛选器和测试现在是普通功能。 它不再是必要的,并且允许使用工厂函数。
Django¶
如果你以前使用 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 中是做不到的。 此语法也用于宏。
Filter 的参数¶
Jinja 为 filters 提供多个参数。 参数传递的语法也不同。 在 Django 中如下所示的模板:
{{ items|join:", " }}
在 Jinja中 看起来像这样:
{{ items|join(', ') }}
它有点冗长,但是它允许使用不同类型的参数(包括变量),并且可以使用多个参数。
测试¶
除 filters 之外,你还可以使用 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。
此外,在Jinja中,Django 的 empty 参数称为 else。 例如,Django 模板:
{% for item in items %}
{{ item }}
{% empty %}
No items!
{% endfor %}
… 在 Jinja 中看起来像这样:
{% for item in items %}
{{ item }}
{% else %}
No items!
{% endfor %}
Cycle¶
Jinja 中不存在{% cycle %}
标记;但是可以通过对循环上下文特殊变量使用 cycle 方法来实现相同的输出。
以下 Django 模板:
{% for user in users %}
<li class="{% cycle 'odd' 'even' %}">{{ user }}</li>
{% endfor %}
...看起来像在金贾:
{% for user in users %}
<li class="{{ loop.cycle('odd', 'even') }}">{{ user }}</li>
{% endfor %}
没有等效的 {% 周期 ... 作为 变量 %}
.
Mako¶
如果到目前为止你已经使用过 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 %>