发布于 2015-09-03 10:04:39 | 238 次阅读 | 评论: 0 | 来源: 网络整理
如果你过去使用一个不同的模板引擎,并且想要转换到 Jinja2 ,这里是一份简小的 指导展示了一些常见的、相似的 Python 文本模板引擎基本语法和语义差异。
Jinja2 与 Jinja1 在 API 使用和模板语法上最为兼容。下面的列表解释了 Jinja1 和 Jinja2 的区别。
如果你之前使用 Django 模板,你应该会发现跟 Jinja2 非常相似。实际上, 很多的语法元素看起来相同,工作也相同。
尽管如此, Jinja2 提供了更多的在之前文档中描述的语法元素,并且某些 工作会有一点不一样。
本节介绍了模板差异。由于 API 是从根本上不同,我们不会再这里赘述。
在 Django 中,方法调用是隐式的。在 Jinja2 中,你必须指定你要调用一个对象。如 此,这段 Django 代码:
{% for page in user.get_created_pages %} ... {% endfor %}
在 Jinja 中应该是这样:
{% for page in user.get_created_pages() %} ... {% endfor %}
这允许你给函数传递变量,且宏也使用这种方式,而这在 Django 中是不可能的。
在 Django 中你可以使用下面的结构来判断是否相等:
{% ifequal foo "bar" %} ... {% else %} ... {% endifequal %}
在 Jinja2 中你可以像通常一样使用 if 语句和操作符来做比较:
{% if foo == 'bar' %} ... {% else %} ... {% endif %}
你也可以在模板中使用多个 elif 分支:
{% if something %} ... {% elif otherthing %} ... {% elif foothing %} ... {% else %} ... {% endif %}
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 %}
因为循环与 Django 中的十分相似,仅有的不兼容是 Jinja2 中循环上下文的特殊变 量名为 loop 而不是 Django 中的 forloop 。
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 并且想要转换到 Jinja2 ,你可以把 Jinja2 配置成 Mako 一 样:
env = Environment('<%', '%>', '${', '}', '%')
环境配置成这样后, Jinja2 应该可以解释一个 Mako 模板的小型子集。 Jinja2 不支持 嵌入 Python 代码,所以你可能需要把它们移出模板。 def 的语法(在 Jinja2 中 def 被叫做宏)并且模板继承也是不同的。下面的 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 %>