从其他模板引擎切换

以下是对 Jinja 语法和其它模板语言之间一些差异的简要指南。有关 Jinja 语法和功能的全面指南,请参阅 模板设计器文档

Django

如果您之前使用过 Django 模板,您会发现 Jinja 非常熟悉。许多语法元素看起来相同并且工作方式相同。但是,Jinja 提供了一些更多的语法元素,并且有些工作方式略有不同。

本节介绍了模板更改。API(包括扩展支持)从根本上不同,因此此处不会介绍。

Django 支持使用 Jinja 作为其模板引擎,请参阅 https://docs.django.ac.cn/en/stable/topics/templates/#support-for-template-engines

方法调用

在 Django 中,方法被隐式调用,无需括号。

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

在 Jinja 中,调用需要使用括号,就像在 Python 中一样。这允许您将变量传递给方法,这在 Django 中是不可能的。此语法还用于调用宏。

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

过滤器参数

在 Django 中,可以在冒号后将一个文本值传递给过滤器。

{{ items|join:", " }}

在 Jinja 中,过滤器可以在括号中获取任意数量的位置参数和关键字参数,就像函数调用一样。参数也可以是变量,而不是文本值。

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

测试

除了过滤器之外,Jinja 还具有与 is 运算符一起使用的“测试”。此运算符与 Python 运算符不同。

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

循环

在 Django 中,循环上下文的特殊变量称为 forloop,并且 empty 用于没有循环项目。

{% for item in items %}
    {{ forloop.counter }}. {{ item }}
{% empty %}
    No items!
{% endfor %}

在 Jinja 中,循环上下文的特殊变量称为 loop,而 else 块用于无循环项目。

{% for item in items %}
    {{ loop.index }}. {{ item }}
{% else %}
    No items!
{% endfor %}

循环

在 Django 中,{% cycle %} 可用于 for 循环,以在每个循环之间交替值。

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

在 Jinja 中,loop 上下文有一个 cycle 方法。

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

循环器还可以分配给变量,并使用 cycle() 全局函数在循环外部或跨循环中使用。

Mako

你可以将 Jinja 配置为更像 Mako

env = Environment(
    block_start_string="<%",
    block_end_string="%>",
    variable_start_string="${",
    variable_end_string="}",
    comment_start_string="<%doc>",
    commend_end_string="</%doc>",
    line_statement_prefix="%",
    line_comment_prefix="##",
)

使用这样配置的环境,Jinja 应该能够在不进行任何更改的情况下解释 Mako 模板的一个小子集。

Jinja 不支持嵌入式 Python 代码,因此你必须将其从模板中移出。你可以使用相同的代码在渲染之前处理数据,或向 Jinja 环境添加全局函数或过滤器。

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 %>