由其他模板引擎轉換

這是關於 Jinja 語法與其他模板語言的一些差異的簡要指南。請參閱 模板設計文件 以取得 Jinja 語法和功能的完整指南。

Django

如果你先前有使用過 Django 範本,你會發現 Jinja 非常熟悉。很多語法元素看起來和工作方式相同。不過,Jinja 提供一些其他的語法元素,而有些在運作上有些微不同。

這一節涵蓋了範本的變更。API,包括擴充功能支援,基本上與此不同,所以在此不會涵蓋。

Django 支援使用 Jinja 作為其模板引擎,請參閱 https://django-docs.dev.org.tw/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 環境。

定義語法(在 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 %>