テンプレートデザイナー ドキュメント

このドキュメントでは、テンプレートエンジンの構文とセマンティクスについて説明します。Jinja テンプレートを作成する際の参照として最も役立ちます。テンプレートエンジンは非常に柔軟であるため、アプリケーションからの設定は、デリミタと未定義値の動作に関して、ここに示されているコードとは多少異なる場合があります。

概要

Jinja テンプレートは、単なるテキストファイルです。Jinja は、テキストベースのフォーマット(HTML、XML、CSV、LaTeX など)を生成できます。Jinja テンプレートは、特定の拡張子を持つ必要はありません。.html.xml、またはその他の拡張子は問題ありません。

テンプレートには、テンプレートがレンダリングされるときに値に置き換えられる変数と、テンプレートのロジックを制御するタグが含まれています。テンプレート構文は、Django と Python によって大きく影響を受けています。

以下は、デフォルトの Jinja 設定を使用した基本事項をいくつか示す最小限のテンプレートです。このドキュメントの後半で詳細を説明します。

<!DOCTYPE html>
<html lang="en">
<head>
    <title>My Webpage</title>
</head>
<body>
    <ul id="navigation">
    {% for item in navigation %}
        <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
    {% endfor %}
    </ul>

    <h1>My Webpage</h1>
    {{ a_variable }}

    {# a comment #}
</body>
</html>

次の例は、デフォルトの設定を示しています。アプリケーション開発者は、{% foo %} の構文設定を <% foo %> などに変更できます。

いくつかの種類のデリミタがあります。デフォルトの Jinja デリミタは次のように設定されています。

  • {% ... %}ステートメント 用です。

  • {{ ... }} は、テンプレート出力に表示される 用です。

  • {# ... #} は、テンプレート出力に含まれない コメント 用です。

行ステートメントとコメント も可能ですが、デフォルトではプレフィックス文字がありません。これらを使用するには、Environment を作成する際に line_statement_prefixline_comment_prefix を設定します。

テンプレートファイルの拡張子

上記のように、ファイルの拡張子に関係なく、任意のファイルをテンプレートとして読み込むことができます。.jinja 拡張子(例: user.html.jinja)を追加すると、一部の IDE やエディタープラグインで使いやすくなる場合がありますが、必須ではありません。後で説明する自動エスケープは、ファイル拡張子に基づいて適用されるため、その場合、追加のサフィックスを考慮する必要があります。

テンプレートを識別するためのもう1つの良いヒューリスティックは、拡張子に関係なく、templates フォルダーにあることです。これは、プロジェクトの一般的なレイアウトです。

変数

テンプレート変数は、テンプレートに渡されるコンテキストディクショナリによって定義されます。

アプリケーションによって渡される変数は、テンプレート内で自由に操作できます。変数には、アクセスできる属性や要素がある場合があります。変数が持つ属性は、その変数を提供するアプリケーションに大きく依存します。

標準の Python __getitem__ 「添字」構文([])に加えて、ドット(.)を使用して変数の属性にアクセスできます。

次の行は同じことを行います。

{{ foo.bar }}
{{ foo['bar'] }}

重要なのは、外側の二重波かっこは変数の一部ではなく、print 文であるということです。タグ内で変数にアクセスする場合は、波かっこを付けないでください。

変数または属性が存在しない場合、未定義の値が返されます。その値をどのように処理できるかは、アプリケーションの設定によって異なります。デフォルトの動作は、印刷または反復処理を行う場合は空の文字列として評価され、その他のすべての操作では失敗します。

実装

便宜上、Jinja の foo.bar は、Python レイヤーで次のことを行います。

  • foobar という名前の属性があるかどうかをチェックします(getattr(foo, 'bar'))。

  • なければ、foo'bar' という項目があるかどうかをチェックします(foo.__getitem__('bar'))。

  • なければ、未定義のオブジェクトを返します。

foo['bar'] は、順序が少し異なる点を除いて、ほぼ同じように動作します。

  • foo'bar' という項目があるかどうかをチェックします。(foo.__getitem__('bar'))。

  • なければ、foobar という名前の属性があるかどうかをチェックします。(getattr(foo, 'bar'))。

  • なければ、未定義のオブジェクトを返します。

これは、オブジェクトが同じ名前の項目と属性を持っている場合に重要です。さらに、attr() フィルターは属性のみを検索します。

フィルター

変数はフィルターによって変更できます。フィルターは、パイプ記号(|)によって変数から分離され、オプションで括弧内の引数を持つことができます。複数のフィルターを連鎖させることができます。1つのフィルターの出力が次のフィルターに適用されます。

たとえば、{{ name|striptags|title }} は、変数 name からすべての HTML タグを削除し、出力をタイトルケースにします(title(striptags(name)))。

引数を受け取るフィルターは、関数呼び出しのように、引数の周囲に括弧があります。たとえば、{{ listx|join(', ') }} は、カンマでリストを結合します(str.join(', ', listx))。

以下の 組み込みフィルターの一覧 には、すべての組み込みフィルターが記載されています。

テスト

フィルターに加えて、いわゆる「テスト」も利用できます。テストは、変数を一般的な式に対してテストするために使用できます。変数または式をテストするには、is とテストの名前を変数の後に追加します。たとえば、変数が定義されているかどうかを確認するには、name is defined を使用できます。これは、name が現在のテンプレートコンテキストで定義されているかどうかによって、true または false を返します。

テストも引数を受け取ることができます。テストが1つの引数しか受け取らない場合は、括弧を省略できます。たとえば、次の2つの式は同じことを行います。

{% if loop.index is divisibleby 3 %}
{% if loop.index is divisibleby(3) %}

以下の 組み込みテストの一覧 には、すべての組み込みテストが記載されています。

コメント

テンプレートの行の一部をコメントアウトするには、デフォルトで {# ... #} に設定されているコメント構文を使用します。これは、デバッグのためにテンプレートの一部をコメントアウトしたり、他のテンプレートデザイナーや自分自身のために情報を追加するのに役立ちます。

{# note: commented-out template because we no longer use this
    {% for user in users %}
        ...
    {% endfor %}
#}

空白の制御

デフォルトの設定では、

  • 末尾の改行が1つ存在する場合、削除されます。

  • その他の空白(スペース、タブ、改行など)は変更されずに返されます。

アプリケーションが Jinja を trim_blocks に設定した場合、テンプレートタグの後の最初の改行が自動的に削除されます(PHP のように)。lstrip_blocks オプションも設定して、行の先頭からブロックの先頭までのタブとスペースを削除できます。(ブロックの先頭に他の文字がある場合は、何も削除されません)。

trim_blockslstrip_blocks の両方が有効になっている場合、ブロックタグを独自の行に配置でき、レンダリング時にブロック行全体が削除され、コンテンツの空白が保持されます。たとえば、trim_blockslstrip_blocks オプションがない場合、このテンプレートは

<div>
    {% if True %}
        yay
    {% endif %}
</div>

div 内に空行が表示されます。

<div>

        yay

</div>

しかし、trim_blockslstrip_blocks の両方が有効になっている場合、テンプレートブロック行が削除され、その他の空白は保持されます。

<div>
        yay
</div>

ブロックの先頭にプラス記号(+)を付けることで、lstrip_blocks の動作を手動で無効にすることができます。

<div>
        {%+ if something %}yay{% endif %}
</div>

同様に、ブロックの末尾にプラス記号(+)を付けることで、trim_blocks の動作を手動で無効にすることができます。

<div>
    {% if something +%}
        yay
    {% endif %}
</div>

テンプレート内の空白を手動で削除することもできます。ブロック(例:For タグ)、コメント、または変数式の先頭または末尾にマイナス記号(-)を追加すると、そのブロックの前後の空白が削除されます。

{% for item in seq -%}
    {{ item }}
{%- endfor %}

これにより、要素間に空白がない状態ですべての要素が生成されます。seq1 から 9 までの数字のリストだった場合、出力は 123456789 になります。

行ステートメント が有効になっている場合、行の先頭までの先頭の空白が自動的に削除されます。

デフォルトでは、Jinja は末尾の改行も削除します。末尾の改行を保持するには、Jinja を keep_trailing_newline に設定します。

注記

タグとマイナス記号の間に空白を追加してはなりません。

有効:

{%- if foo -%}...{% endif %}

無効:

{% - if foo - %}...{% endif %}

エスケープ

Jinjaが変数やブロックとして処理する部分を無視することが、場合によっては望ましく、必要となることもあります。たとえば、デフォルトの構文で、テンプレート内で{{を生の文字列として使用し、変数を開始しないようにするには、工夫が必要です。

リテラルな変数デリミタ({{)を出力する最も簡単な方法は、変数式を使用することです。

{{ '{{' }}

より大きなセクションの場合、ブロックをrawとしてマークすることが理にかなっています。たとえば、テンプレートにJinja構文の例を含めるには、このスニペットを使用できます。

{% raw %}
    <ul>
    {% for item in seq %}
        <li>{{ item }}</li>
    {% endfor %}
    </ul>
{% endraw %}

注記

{% raw -%}タグの末尾のマイナス記号は、生のデータの先頭文字の前にあるすべてのスペースと改行を削除します。

行ステートメント

アプリケーションによって行ステートメントが有効になっている場合、行をステートメントとしてマークできます。たとえば、行ステートメントプレフィックスが#に設定されている場合、次の2つの例は同等です。

<ul>
# for item in seq
    <li>{{ item }}</li>
# endfor
</ul>

<ul>
{% for item in seq %}
    <li>{{ item }}</li>
{% endfor %}
</ul>

行ステートメントプレフィックスは、行のどこにでも表示できますが、その前にテキストがあってはなりません。可読性を高めるために、ブロックを開始するステートメント(forifelifなど)はコロンで終わる場合があります。

# for item in seq:
    ...
# endfor

注記

行ステートメントは、括弧、中括弧、角括弧が開いている場合、複数行にまたがる場合があります。

<ul>
# for href, caption in [('index.html', 'Index'),
                        ('about.html', 'About')]:
    <li><a href="{{ href }}">{{ caption }}</a></li>
# endfor
</ul>

Jinja 2.2以降、行ベースのコメントも使用できます。たとえば、行コメントプレフィックスが##に設定されている場合、##から行末までのすべてが(改行記号を除いて)無視されます。

# for item in seq:
    <li>{{ item }}</li>     ## this comment is ignored
# endfor

テンプレート継承

Jinjaの最も強力な機能はテンプレート継承です。テンプレート継承により、サイトの共通要素をすべて含む基本的な「スケルトン」テンプレートを作成し、子テンプレートがオーバーライドできる**ブロック**を定義できます。

複雑に聞こえますが、非常に基本的なものです。例から理解するのが最も簡単です。

基本テンプレート

このテンプレート(base.htmlと呼びます)は、シンプルな2カラムページに使用できる単純なHTMLスケルトン文書を定義しています。「子」テンプレートの役割は、空のブロックにコンテンツを入力することです。

<!DOCTYPE html>
<html lang="en">
<head>
    {% block head %}
    <link rel="stylesheet" href="style.css" />
    <title>{% block title %}{% endblock %} - My Webpage</title>
    {% endblock %}
</head>
<body>
    <div id="content">{% block content %}{% endblock %}</div>
    <div id="footer">
        {% block footer %}
        &copy; Copyright 2008 by <a href="http://domain.invalid/">you</a>.
        {% endblock %}
    </div>
</body>
</html>

この例では、{% block %}タグは、子テンプレートが入力できる4つのブロックを定義しています。すべてのblockタグが行うことは、テンプレートエンジンに対して、子テンプレートがテンプレート内のそれらのプレースホルダーをオーバーライドできることを伝えることです。

blockタグはifなどの他のブロックの中に置くことができますが、ifブロックが実際にレンダリングされるかどうかに関係なく、常に実行されます。

子テンプレート

子テンプレートは次のようになります。

{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
    {{ super() }}
    <style type="text/css">
        .important { color: #336699; }
    </style>
{% endblock %}
{% block content %}
    <h1>Index</h1>
    <p class="important">
      Welcome to my awesome homepage.
    </p>
{% endblock %}

{% extends %}タグがここで重要になります。テンプレートエンジンに、このテンプレートが別のテンプレートを「拡張」することを伝えます。テンプレートシステムがこのテンプレートを評価すると、最初に親を見つけます。extendsタグは、テンプレートの最初のタグである必要があります。それより前のものは通常出力され、混乱を招く可能性があります。この動作とそれを活用する方法の詳細については、Null-Default Fallbackを参照してください。また、ブロックは、周囲の条件が真または偽に評価されるかどうかに関係なく、常に埋め込まれます。

テンプレートのファイル名は、テンプレートローダーによって異なります。たとえば、FileSystemLoaderを使用すると、ファイル名を与えることで他のテンプレートにアクセスできます。スラッシュを使用して、サブディレクトリのテンプレートにアクセスできます。

{% extends "layout/default.html" %}

しかし、この動作は、Jinjaを埋め込んでいるアプリケーションによって異なる場合があります。子テンプレートはfooterブロックを定義していないため、親テンプレートからの値が代わりに使用されることに注意してください。

同じテンプレート内で同じ名前の{% block %}タグを複数定義することはできません。この制限が存在するのは、ブロックタグが「両方向」に機能するためです。つまり、ブロックタグは単にプレースホルダーを提供するだけでなく、*親*のプレースホルダーを埋めるコンテンツも定義します。テンプレート内に同じ名前の{% block %}タグが2つある場合、そのテンプレートの親はどちらのブロックのコンテンツを使用するかを知りません。

ブロックを複数回出力する場合は、特別なself変数を使用し、その名前でブロックを呼び出すことができます。

<title>{% block title %}{% endblock %}</title>
<h1>{{ self.title() }}</h1>
{% block body %}{% endblock %}

スーパーブロック

super()を呼び出すことで、親ブロックのコンテンツをレンダリングできます。これにより、親ブロックの結果が返されます。

{% block sidebar %}
    <h3>Table Of Contents</h3>
    ...
    {{ super() }}
{% endblock %}

ネストされたextends

複数のレベルの{% extends %}の場合、super参照は連鎖させることができます(super.super()のように)。継承ツリーのレベルをスキップします。

例:

# parent.tmpl
body: {% block body %}Hi from parent.{% endblock %}

# child.tmpl
{% extends "parent.tmpl" %}
{% block body %}Hi from child. {{ super() }}{% endblock %}

# grandchild1.tmpl
{% extends "child.tmpl" %}
{% block body %}Hi from grandchild1.{% endblock %}

# grandchild2.tmpl
{% extends "child.tmpl" %}
{% block body %}Hi from grandchild2. {{ super.super() }} {% endblock %}

child.tmplをレンダリングすると、body: Hi from child. Hi from parent.が得られます。

grandchild1.tmplをレンダリングすると、body: Hi from grandchild1.が得られます。

grandchild2.tmplをレンダリングすると、body: Hi from grandchild2. Hi from parent.が得られます。

名前付きブロックエンドタグ

Jinjaでは、可読性を高めるために、エンドタグの後にブロックの名前を付けることができます。

{% block sidebar %}
    {% block inner_sidebar %}
        ...
    {% endblock inner_sidebar %}
{% endblock sidebar %}

ただし、endblockの後の名前は、ブロック名と一致する必要があります。

ブロックのネストとスコープ

より複雑なレイアウトのために、ブロックをネストできます。ただし、デフォルトでは、ブロックは外部スコープの変数にアクセスできません。

{% for item in seq %}
    <li>{% block loop_item %}{{ item }}{% endblock %}</li>
{% endfor %}

この例では、itemはブロック内で使用できないため、空の<li>アイテムが出力されます。その理由は、ブロックが子テンプレートによって置き換えられる場合、ブロックで定義されていないか、コンテキストに渡されていない変数が表示されるためです。

Jinja 2.2以降、ブロック宣言にscoped修飾子を付けることで、ブロックで使用できる変数を明示的に指定できます。

{% for item in seq %}
    <li>{% block loop_item scoped %}{{ item }}{% endblock %}</li>
{% endfor %}

ブロックをオーバーライドする場合、scoped修飾子を指定する必要はありません。

必須ブロック

ブロックはrequiredとしてマークできます。ある時点でオーバーライドする必要がありますが、必ずしも直接の子テンプレートによってオーバーライドする必要はありません。必須ブロックには、スペースとコメントのみを含めることができ、直接レンダリングすることはできません。

page.txt
{% block body required %}{% endblock %}
issue.txt
{% extends "page.txt" %}
bug_report.txt
{% extends "issue.txt" %}
{% block body %}Provide steps to demonstrate the bug.{% endblock %}

page.txtまたはissue.txtをレンダリングすると、bodyブロックをオーバーライドしないため、TemplateRuntimeErrorが発生します。bug_report.txtをレンダリングすると、ブロックをオーバーライドするため、正常に実行されます。

scopedと組み合わせると、required修飾子はscoped修飾子の*後*に配置する必要があります。有効な例をいくつか示します。

{% block body scoped %}{% endblock %}
{% block body required %}{% endblock %}
{% block body scoped required %}{% endblock %}

テンプレートオブジェクト

extendsinclude、そしてimportは、読み込むテンプレートの名前の代わりに、テンプレートオブジェクトを受け取ることができます。これは、Pythonコードを使用して最初にテンプレートを読み込み、renderに渡すことができるため、高度な状況で役立つ場合があります。

if debug_mode:
    layout = env.get_template("debug_layout.html")
else:
    layout = env.get_template("layout.html")

user_detail = env.get_template("user/detail.html")
return user_detail.render(layout=layout)
{% extends layout %}

renderに渡されたテンプレートオブジェクトを持つ変数が、文字列の代わりにextendsに渡されていることに注意してください。

HTMLエスケープ

テンプレートからHTMLを生成する場合、変数に結果のHTMLに影響を与える文字が含まれているリスクが常に存在します。2つのアプローチがあります。

  1. 各変数を手動でエスケープする。

  2. デフォルトですべてを自動的にエスケープする。

Jinjaは両方ともサポートしています。どちらを使用するかは、アプリケーションの設定によって異なります。デフォルトの設定は自動エスケープではありません。様々な理由から

  • 安全な値を除くすべてをエスケープすると、HTMLを含まないことがわかっている変数(例:数値、ブール値)もJinjaによってエスケープされるため、パフォーマンスに大きな影響を与える可能性があります。

  • 変数の安全に関する情報は非常に脆弱です。安全な値と安全でない値を強制することによって、戻り値が二重にエスケープされたHTMLになる可能性があります。

手動エスケープによる操作

手動エスケープが有効になっている場合、必要に応じて変数をエスケープする責任は**あなた**にあります。何をエスケープする必要がありますか?以下の文字のいずれか(><&、または")が含まれている可能性のある変数がある場合、変数に適切に形成され信頼できるHTMLが含まれていない限り、**必ず**エスケープする必要があります。エスケープは、変数を|eフィルタに通すことで行います。

{{ user.username|e }}

自動エスケープによる操作

自動エスケープが有効になっている場合、明示的に安全とマークされた値を除き、すべてがデフォルトでエスケープされます。変数と式は、次のいずれかで安全とマークできます。

  1. アプリケーションによってmarkupsafe.Markupを使用してコンテキスト辞書に設定される。

  2. |safeフィルタを使用してテンプレートで設定される。

安全とマークした文字列が、そのマークを理解しない他のPythonコードを通過すると、マークが失われる可能性があります。データがいつ安全とマークされ、テンプレートに到着する前にどのように処理されるかに注意してください。

エスケープされた値が安全とマークされていない場合、自動エスケープが行われ、二重にエスケープされた文字が生成されます。既に安全だがマークされていないデータがあることがわかっている場合は、Markupでラップするか、|safeフィルタを使用してください。

Jinja関数(マクロ、superself.BLOCKNAME)は、常に安全とマークされたテンプレートデータを返します。

自動エスケープが有効なテンプレート内の文字列リテラルは、ネイティブのPython文字列は安全ではないため、安全ではないと見なされます。

制御構造の一覧

制御構造とは、プログラムの流れを制御するすべてのもの、つまり条件文(if/elif/else)、forループ、マクロやブロックなどを指します。デフォルトの構文では、制御構造は{% ... %}ブロック内に表示されます。

For

シーケンス内の各項目をループします。例えば、usersという変数で提供されたユーザーの一覧を表示するには

<h1>Members</h1>
<ul>
{% for user in users %}
  <li>{{ user.username|e }}</li>
{% endfor %}
</ul>

テンプレート内の変数はオブジェクトのプロパティを保持するため、dictなどのコンテナを反復処理できます。

<dl>
{% for key, value in my_dict.items() %}
    <dt>{{ key|e }}</dt>
    <dd>{{ value|e }}</dd>
{% endfor %}
</dl>

Pythonの辞書は、表示したい順序にならない場合があります。順序が重要な場合は、|dictsortフィルタを使用してください。

<dl>
{% for key, value in my_dict | dictsort %}
    <dt>{{ key|e }}</dt>
    <dd>{{ value|e }}</dd>
{% endfor %}
</dl>

forループブロック内では、いくつかの特別な変数にアクセスできます。

変数

説明

loop.index

ループの現在の反復回数。(1から始まるインデックス)

loop.index0

ループの現在の反復回数。(0から始まるインデックス)

loop.revindex

ループの終わりからの反復回数。(1から始まるインデックス)

loop.revindex0

ループの終わりからの反復回数。(0から始まるインデックス)

loop.first

最初の反復の場合True。

loop.last

最後の反復の場合True。

loop.length

シーケンス内のアイテム数。

loop.cycle

シーケンスのリスト間を循環するためのヘルパー関数。下記の説明を参照。

loop.depth

レンダリングが現在どの深さの再帰ループにあるかを示します。レベル1から始まります。

loop.depth0

レンダリングが現在どの深さの再帰ループにあるかを示します。レベル0から始まります。

loop.previtem

ループの前の反復からのアイテム。最初の反復中は未定義。

loop.nextitem

ループの次の反復からのアイテム。最後の反復中は未定義。

loop.changed(*val)

前に異なる値で呼び出された場合(またはまったく呼び出されなかった場合)True。

forループ内では、ループのたびに文字列/変数のリスト間を循環するために、特別なloop.cycleヘルパーを使用できます。

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

Jinja 2.1以降、ループに依存しない循環を可能にする追加のcycleヘルパーが存在します。詳細については、グローバル関数のリストを参照してください。

Pythonとは異なり、ループ内でbreakまたはcontinueすることはできません。ただし、反復処理中にシーケンスをフィルタリングすることで、アイテムをスキップできます。次の例では、非表示になっているユーザーをすべてスキップします。

{% for user in users if not user.hidden %}
    <li>{{ user.username|e }}</li>
{% endfor %}

利点は、特別なloop変数が正しくカウントされることです。つまり、反復処理されなかったユーザーはカウントされません。

シーケンスが空だったか、フィルタリングによってシーケンスからすべてのアイテムが削除されたために反復処理が行われなかった場合は、elseを使用してデフォルトブロックをレンダリングできます。

<ul>
{% for user in users %}
    <li>{{ user.username|e }}</li>
{% else %}
    <li><em>no users found</em></li>
{% endfor %}
</ul>

Pythonでは、elseブロックは対応するループがbreakしなかった場合に実行されます。Jinjaループはbreakできないため、elseキーワードの動作がわずかに異なります。

ループを再帰的に使用することもできます。これは、サイトマップやRDFaなどの再帰的なデータを取り扱う場合に役立ちます。ループを再帰的に使用するには、基本的にループ定義にrecursive修飾子を追加し、再帰したい新しいイテラブルでloop変数を呼び出す必要があります。

次の例は、再帰ループを使用したサイトマップを実装しています。

<ul class="sitemap">
{%- for item in sitemap recursive %}
    <li><a href="{{ item.href|e }}">{{ item.title }}</a>
    {%- if item.children -%}
        <ul class="submenu">{{ loop(item.children) }}</ul>
    {%- endif %}</li>
{%- endfor %}
</ul>

loop変数は常に最も近い(内側の)ループを参照します。複数のレベルのループがある場合、再帰的に使用したいループの後に{% set outer_loop = loop %}と書くことで、loop変数を再バインドできます。その後、{{ outer_loop(...) }}を使用して呼び出すことができます。

ループ内の代入は反復の最後にクリアされ、ループのスコープを超えて存続することはできないことに注意してください。以前のバージョンのJinjaには、状況によっては代入が機能するように見えるバグがありました。これはサポートされていません。代入で、これに対処する方法の詳細を参照してください。

前回の反復以降に値が変更されたかどうか、または次回の反復で値が変更されるかどうかを確認するだけの場合、previtemnextitemを使用できます。

{% for value in values %}
    {% if loop.previtem is defined and value > loop.previtem %}
        The value just increased!
    {% endif %}
    {{ value }}
    {% if loop.nextitem is defined and loop.nextitem > value %}
        The value will increase even more!
    {% endif %}
{% endfor %}

値が変更されたかどうかだけを気にする場合は、changedを使用する方が簡単です。

{% for entry in entries %}
    {% if loop.changed(entry.category) %}
        <h2>{{ entry.category }}</h2>
    {% endif %}
    <p>{{ entry.message }}</p>
{% endfor %}

If

Jinjaのif文は、Pythonのif文と同様です。最も単純な形式では、変数が定義されている、空ではない、偽ではないかどうかをテストするために使用できます。

{% if users %}
<ul>
{% for user in users %}
    <li>{{ user.username|e }}</li>
{% endfor %}
</ul>
{% endif %}

複数の分岐には、Pythonと同様にelifelseを使用できます。より複雑なも使用できます。

{% if kenny.sick %}
    Kenny is sick.
{% elif kenny.dead %}
    You killed Kenny!  You bastard!!!
{% else %}
    Kenny looks okay --- so far
{% endif %}

`if` は、インライン式 および ループフィルタリング として使用することもできます。

マクロ

マクロは、一般的なプログラミング言語の関数と同様です。よく使う慣用句を再利用可能な関数としてまとめることで、「DRY(Don't Repeat Yourself)」を実現するのに役立ちます。

フォーム要素をレンダリングするマクロの小さな例を次に示します。

{% macro input(name, value='', type='text', size=20) -%}
    <input type="{{ type }}" name="{{ name }}" value="{{
        value|e }}" size="{{ size }}">
{%- endmacro %}

マクロは、名前空間内で関数のように呼び出すことができます。

<p>{{ input('username') }}</p>
<p>{{ input('password', type='password') }}</p>

マクロが別のテンプレートで定義されている場合は、まずインポートする必要があります。

マクロ内では、3つの特別な変数にアクセスできます。

varargs

マクロに渡された位置引数が、マクロで受け入れる引数よりも多い場合、それらの引数は値のリストとして特別なvarargs変数に格納されます。

kwargs

varargsと同様ですが、キーワード引数用です。使用されなかったすべてのキーワード引数は、この特別な変数に格納されます。

caller

マクロがcallタグから呼び出された場合、呼び出し元は呼び出し可能なマクロとしてこの変数に格納されます。

マクロは、内部の詳細の一部も公開します。マクロオブジェクトには、次の属性があります。

name

マクロの名前です。{{ input.name }}input を出力します。

arguments

マクロが受け入れる引数の名前のタプルです。

catch_kwargs

マクロが追加のキーワード引数を受け入れる場合(つまり、特別なkwargs変数にアクセスする場合)、これはtrueです。

catch_varargs

マクロが追加の位置引数を受け入れる場合(つまり、特別なvarargs変数にアクセスする場合)、これはtrueです。

caller

マクロが特別なcaller変数にアクセスし、callタグから呼び出される可能性がある場合、これはtrueです。

マクロ名がアンダースコアで始まる場合、エクスポートされず、インポートできません。

Jinja のスコープの動作のため、子テンプレートのマクロは親テンプレートのマクロを上書きしません。次の例では、「CHILD」ではなく「LAYOUT」が出力されます。

layout.txt
{% macro foo() %}LAYOUT{% endmacro %}
{% block body %}{% endblock %}
child.txt
{% extends 'layout.txt' %}
{% macro foo() %}CHILD{% endmacro %}
{% block body %}{{ foo() }}{% endblock %}

Call

場合によっては、マクロを別のマクロに渡すことが役立つことがあります。この目的のために、特別なcallブロックを使用できます。次の例は、call機能を利用するマクロとその使用方法を示しています。

{% macro render_dialog(title, class='dialog') -%}
    <div class="{{ class }}">
        <h2>{{ title }}</h2>
        <div class="contents">
            {{ caller() }}
        </div>
    </div>
{%- endmacro %}

{% call render_dialog('Hello World') %}
    This is a simple dialog rendered by using a macro and
    a call block.
{% endcall %}

callブロックに引数を戻すことも可能です。これにより、ループの代替として役立ちます。一般的に、callブロックは名前のないマクロとまったく同じように動作します。

callブロックを引数付きで使用する方法の例を次に示します。

{% macro dump_users(users) -%}
    <ul>
    {%- for user in users %}
        <li><p>{{ user.username|e }}</p>{{ caller(user) }}</li>
    {%- endfor %}
    </ul>
{%- endmacro %}

{% call(user) dump_users(list_of_user) %}
    <dl>
        <dt>Realname</dt>
        <dd>{{ user.realname|e }}</dd>
        <dt>Description</dt>
        <dd>{{ user.description }}</dd>
    </dl>
{% endcall %}

フィルター

フィルターセクションを使用すると、テンプレートデータのブロックに通常の Jinja フィルターを適用できます。コードを特別なfilterセクションで囲むだけです。

{% filter upper %}
    This text becomes uppercase
{% endfilter %}

引数を受け取るフィルターは、次のように呼び出すことができます。

{% filter center(100) %}Center this{% endfilter %}

代入

コードブロック内では、変数に値を代入することもできます。最上位レベル(ブロック、マクロ、ループの外側)での代入は、最上位レベルのマクロのようにテンプレートからエクスポートされ、他のテンプレートからインポートできます。

代入にはsetタグを使用し、複数のターゲットを持つことができます。

{% set navigation = [('index.html', 'Index'), ('about.html', 'About')] %}
{% set key, value = call_something() %}

スコープの動作

ブロック内で変数を設定して、その外側で表示させることはできないことに注意してください。これはループにも適用されます。この規則の唯一の例外は、スコープを導入しないif文です。そのため、次のテンプレートは期待どおりに動作しません。

{% set iterated = false %}
{% for item in seq %}
    {{ item }}
    {% set iterated = true %}
{% endfor %}
{% if not iterated %} did not iterate {% endif %}

Jinja構文ではこれを行うことができません。代わりに、ループのelseブロックや特別なloop変数などの代替構成を使用してください。

{% for item in seq %}
    {{ item }}
{% else %}
    did not iterate
{% endfor %}

バージョン2.10以降、より複雑なユースケースは、スコープ全体での変更の伝播を可能にする名前空間オブジェクトを使用して処理できます。

{% set ns = namespace(found=false) %}
{% for item in items %}
    {% if item.check_something() %}
        {% set ns.found = true %}
    {% endif %}
    * {{ item.title }}
{% endfor %}
Found item having something: {{ ns.found }}

setタグでのobj.attr表記は、名前空間オブジェクトに対してのみ許可されています。他のオブジェクトの属性を代入しようとすると、例外が発生します。

変更ログ

バージョン 2.10 で追加: 名前空間オブジェクトのサポートを追加

ブロック代入

変更ログ

バージョン 2.8 で追加。

Jinja 2.8 以降、ブロック代入を使用してブロックの内容を変数名にキャプチャすることもできます。これは、マクロの代替として、状況によっては役立ちます。この場合、等号と値を使用する代わりに、変数名だけを書き、{% endset %}までをキャプチャします。

{% set navigation %}
    <li><a href="/">Index</a>
    <li><a href="/downloads">Downloads</a>
{% endset %}

navigation変数には、ナビゲーションのHTMLソースが含まれます。

変更ログ

バージョン 2.10 で変更。

Jinja 2.10 以降、ブロック代入はフィルターをサポートしています。

{% set reply | wordwrap %}
    You wrote:
    {{ message }}
{% endset %}

Extends

extendsタグを使用して、あるテンプレートを別のテンプレートから拡張できます。ファイル内に複数のextendsタグを含めることができますが、一度に実行できるのは1つだけです。

上記のテンプレートの継承に関するセクションを参照してください。

ブロック

ブロックは継承に使用され、プレースホルダーと置換の両方の役割を果たします。テンプレートの継承セクションで詳細に説明されています。

Include

includeタグは別のテンプレートをレンダリングし、その結果を現在のテンプレートに出力します。

{% include 'header.html' %}
Body goes here.
{% include 'footer.html' %}

デフォルトでは、インクルードされたテンプレートは現在のテンプレートのコンテキストにアクセスできます。without contextを使用して、代わりに別のコンテキストを使用します。with contextも有効ですが、デフォルトの動作です。インポートコンテキストの動作を参照してください。

インクルードされたテンプレートは、別のテンプレートをextendし、そのテンプレート内のブロックを上書きできます。ただし、現在のテンプレートは、インクルードされたテンプレートが出力するブロックを上書きできません。

テンプレートが存在しない場合、ステートメントを無視するにはignore missingを使用します。コンテキストの可視性ステートメントの *前* に配置する必要があります。

{% include "sidebar.html" without context %}
{% include "sidebar.html" ignore missing %}
{% include "sidebar.html" ignore missing with context %}
{% include "sidebar.html" ignore missing without context %}

テンプレートのリストが指定されている場合、見つからないテンプレートがないものが表示されるまで、順に試行されます。これによりignore missingと共に使用して、いずれのテンプレートも存在しない場合に無視できます。

{% include ['page_detailed.html', 'page.html'] %}
{% include ['special_sidebar.html', 'sidebar.html'] ignore missing %}

テンプレート名またはテンプレートオブジェクトのいずれかの変数をステートメントに渡すこともできます。

Import

Jinja は、よく使うコードをマクロにまとめることをサポートしています。これらのマクロは異なるテンプレートに配置し、そこからインポートできます。これはPythonのインポート文と同様に機能します。インポートはキャッシュされ、インポートされたテンプレートは、デフォルトでは現在のテンプレート変数ではなく、グローバル変数にのみアクセスできることに注意することが重要です。インポートとインクルードのコンテキスト動作の詳細については、インポートコンテキストの動作を参照してください。

テンプレートをインポートする方法は2つあります。完全なテンプレートを変数にインポートするか、そこから特定のマクロ/エクスポートされた変数を要求できます。

フォームをレンダリングするヘルパーモジュール(forms.htmlと呼ばれる)があるとします。

{% macro input(name, value='', type='text') -%}
    <input type="{{ type }}" value="{{ value|e }}" name="{{ name }}">
{%- endmacro %}

{%- macro textarea(name, value='', rows=10, cols=40) -%}
    <textarea name="{{ name }}" rows="{{ rows }}" cols="{{ cols
        }}">{{ value|e }}</textarea>
{%- endmacro %}

テンプレートの変数とマクロにアクセスする最も簡単で柔軟な方法は、テンプレートモジュール全体を変数にインポートすることです。これにより、属性にアクセスできます。

{% import 'forms.html' as forms %}
<dl>
    <dt>Username</dt>
    <dd>{{ forms.input('username') }}</dd>
    <dt>Password</dt>
    <dd>{{ forms.input('password', type='password') }}</dd>
</dl>
<p>{{ forms.textarea('comment') }}</p>

または、テンプレートから特定の名前を現在の名前空間にインポートできます。

{% from 'forms.html' import input as input_field, textarea %}
<dl>
    <dt>Username</dt>
    <dd>{{ input_field('username') }}</dd>
    <dt>Password</dt>
    <dd>{{ input_field('password', type='password') }}</dd>
</dl>
<p>{{ textarea('comment') }}</p>

1つ以上のアンダースコアで始まるマクロと変数はプライベートであり、インポートできません。

変更ログ

バージョン 2.4 で変更: テンプレートオブジェクトがテンプレートコンテキストに渡された場合、そのオブジェクトからインポートできます。

インポートコンテキストの動作

デフォルトでは、インクルードされたテンプレートには現在のコンテキストが渡され、インポートされたテンプレートには渡されません。これは、インクルードとは異なり、インポートはキャッシュされるためです。インポートは多くの場合、マクロを保持するモジュールとしてのみ使用されます。

この動作は、with contextまたはwithout contextをインポート/インクルードディレクティブに追加することで明示的に変更できます。これにより、現在のコンテキストをテンプレートに渡すことができ、キャッシングは自動的に無効になります。

ここに2つの例を示します。

{% from 'forms.html' import input with context %}
{% include 'header.html' without context %}

注記

Jinja 2.0では、インクルードされたテンプレートに渡されたコンテキストには、テンプレート内で定義された変数は含まれていませんでした。実際、これは動作しませんでした。

{% for box in boxes %}
    {% include "render_box.html" %}
{% endfor %}

インクルードされたテンプレートrender_box.htmlは、Jinja 2.0ではboxにアクセスできません。Jinja 2.1以降、render_box.htmlはアクセスできるようになりました。

Jinjaでは、あらゆる場所で基本的な式を使用できます。これらは通常のPythonと非常に似たように動作します。Pythonを使用していない場合でも、快適に操作できるはずです。

リテラル

最も単純な形式の式はリテラルです。リテラルは、文字列や数値などのPythonオブジェクトを表すものです。次のリテラルが存在します。

"Hello World"

二重引用符または単一引用符で囲まれたすべてのものは文字列です。テンプレート内で文字列が必要な場合(例:関数呼び出しやフィルタへの引数として、またはテンプレートを拡張またはインクルードする場合)に役立ちます。

42 / 123_456

整数とは、小数点のない整数です。可読性を高めるために、「_」文字を使用してグループを区切ることができます。

42.23 / 42.1e2 / 123_456.789

浮動小数点数は、「.」を小数点として使用して記述できます。「e」の大文字または小文字を使用して、指数部分を指定した指数表記で記述することもできます。「_」文字を使用して可読性を高めるためにグループを区切ることができますが、指数部分では使用できません。

['list', 'of', 'objects']

ブラケットで囲まれたすべてのものはリストです。リストは、反復処理する順序データの格納に役立ちます。たとえば、リストとタプルを使用してforループでリンクのリストを簡単に作成できます。

<ul>
{% for href, caption in [('index.html', 'Index'), ('about.html', 'About'),
                         ('downloads.html', 'Downloads')] %}
    <li><a href="{{ href }}">{{ caption }}</a></li>
{% endfor %}
</ul>
('tuple', 'of', 'values')

タプルは、変更できない(「不変」)リストのようなものです。タプルにアイテムが1つしかない場合は、コンマを付ける必要があります(('1-tuple',))。タプルは通常、2つ以上の要素のアイテムを表すために使用されます。詳細は上記のリストの例を参照してください。

{'dict': 'of', 'key': 'and', 'value': 'pairs'}

Pythonの辞書は、キーと値を組み合わせた構造です。キーは一意でなければならず、常に値が正確に1つあります。辞書はテンプレートではほとんど使用されません。xmlattr()フィルタなど、まれなケースで役立ちます。

true / false

trueは常にtrueであり、falseは常にfalseです。

注記

特別な定数truefalsenoneは実際には小文字です。過去に混乱を引き起こしたため(Trueはfalseと見なされた未定義の変数に展開されていました)、3つすべてをタイトルケース(TrueFalseNone)で記述することもできます。ただし、一貫性のため(すべてのJinja識別子は小文字です)、小文字バージョンを使用する必要があります。

算術演算

Jinjaでは、値を計算できます。テンプレートではほとんど役立ちませんが、完全性のために存在します。次の演算子がサポートされています。

+

2つのオブジェクトを足し合わせます。通常、オブジェクトは数値ですが、両方が文字列またはリストの場合は、このように連結できます。ただし、これは文字列を連結する推奨方法ではありません!文字列の連結については、~演算子を参照してください。{{ 1 + 1 }}2です。

-

2番目の数値を1番目の数値から引きます。{{ 3 - 2 }}1です。

/

2つの数値を割り算します。戻り値は浮動小数点になります。{{ 1 / 2 }}{{ 0.5 }}です。

//

2つの数値を割り算し、切り捨てられた整数の結果を返します。{{ 20 // 7 }}2です。

%

整数除算の剰余を計算します。{{ 11 % 7 }}4です。

*

左オペランドに右オペランドを掛けます。{{ 2 * 2 }}4を返します。これは、文字列を複数回繰り返すためにも使用できます。{{ '=' * 80 }}は、80個の等号のバーを出力します。

**

左オペランドを右オペランドのべき乗にします。{{ 2**3 }}8を返します。

Pythonとは異なり、連鎖したべき乗は左から右に評価されます。{{ 3**3**3 }}はJinjaでは(3**3)**3として評価されますが、Pythonでは3**(3**3)として評価されます。Jinjaでは括弧を使用して、目的の順序を明確に指定してください。通常、テンプレートで実行するよりも、Pythonで拡張数学を実行して結果をrenderに渡す方が適切です。

この動作は、アップグレードパスを導入できる場合、将来Pythonに合わせて変更される可能性があります。

比較

==

等価性を比較します。

!=

非等価性を比較します。

>

左辺が右辺より大きい場合、true

>=

左辺が右辺以上の場合、true

<

左辺が右辺より小さい場合、true

<=

左辺が右辺以下の場合、true

論理演算

if文、forフィルタリング、およびif式では、複数の式を組み合わせることが役立つ場合があります。

and

左オペランドと右オペランドの両方がtrueの場合、trueを返します。

or

左オペランドまたは右オペランドがtrueの場合、trueを返します。

not

ステートメントを否定します(下記参照)。

(expr)

括弧は式をグループ化します。

注記

is演算子とin演算子は、中置記法を使用して否定もサポートします。foo is not barfoo not in barは、not foo is barnot foo in barの代わりに使用できます。その他のすべての式には、接頭辞記法が必要です:not (foo and bar).

その他の演算子

次の演算子は非常に役立ちますが、他のいずれのカテゴリにも当てはまりません。

in

シーケンス/マッピングの包含テストを実行します。左オペランドが右オペランドに含まれている場合、trueを返します。{{ 1 in [1, 2, 3] }}は、たとえばtrueを返します。

is

テストを実行します。

|(パイプ、縦棒)

フィルタを適用します。

~(チルダ)

すべてのオペランドを文字列に変換し、連結します。

{{ "Hello " ~ name ~ "!" }}は(name'John'に設定されていると仮定して)Hello John!を返します。

()

呼び出し可能なオブジェクトを呼び出します:{{ post.render() }}。括弧内では、Pythonのように位置引数とキーワード引数を使用できます。

{{ post.render(user, full=true) }}.

. / []

オブジェクトの属性を取得します。(変数を参照)

if式

インラインif式を使用することもできます。これは、状況によっては役立ちます。たとえば、変数が定義されている場合はあるテンプレートから拡張し、そうでない場合はデフォルトのレイアウトテンプレートから拡張するために使用できます。

{% extends layout_template if layout_template is defined else 'default.html' %}

一般的な構文は<do something> if <something is true> else <do something else>です。

else部分は省略可能です。指定しない場合、elseブロックは暗黙的にUndefinedオブジェクトに評価されます(環境のundefinedの設定に関わらず)。

{{ "[{}]".format(page.title) if page.title }}

Pythonメソッド

変数の型で定義されているメソッドも使用できます。メソッド呼び出しから返される値は、式の値として使用されます。文字列で定義されているメソッドを使用する例を以下に示します(page.titleが文字列の場合)。

{{ page.title.capitalize() }}

これは、ユーザー定義型のメソッドにも適用されます。Foo型の変数fにメソッドbarが定義されている場合、次のように実行できます。

{{ f.bar(value) }}

演算子メソッドも期待通りに機能します。たとえば、%は文字列に対してprintfスタイルを実装します。

{{ "Hello, %s!" % name }}

ただし、その場合は.formatメソッドを使用することをお勧めします(テンプレートのレンダリングというコンテキストでは少し不自然ですが)。

{{ "Hello, {}!".format(name) }}

組み込みフィルタのリスト

abs()

forceescape()

map()

select()

unique()

attr()

format()

max()

selectattr()

upper()

batch()

groupby()

min()

slice()

urlencode()

capitalize()

indent()

pprint()

sort()

urlize()

center()

int()

random()

string()

wordcount()

default()

items()

reject()

striptags()

wordwrap()

dictsort()

join()

rejectattr()

sum()

xmlattr()

escape()

last()

replace()

title()

filesizeformat()

length()

reverse()

tojson()

first()

list()

round()

trim()

float()

lower()

safe()

truncate()

jinja-filters.abs(x, /)

引数の絶対値を返します。

jinja-filters.attr(obj: Any, name: str) jinja2.runtime.Undefined | Any

オブジェクトの属性を取得します。foo|attr("bar")foo.barのように機能しますが、常に属性が返され、項目は検索されません。

詳細は購読に関する注意事項を参照してください。

jinja-filters.batch(value: 't.Iterable[V]', linecount: int, fill_with: 't.Optional[V]' = None) 't.Iterator[t.List[V]]'

アイテムをバッチ処理するフィルタです。sliceとほぼ同じですが、逆方向に機能します。指定された数のアイテムを含むリストのリストを返します。2番目のパラメータを指定すると、不足しているアイテムを埋めるために使用されます。この例を参照してください。

<table>
{%- for row in items|batch(3, '&nbsp;') %}
  <tr>
  {%- for column in row %}
    <td>{{ column }}</td>
  {%- endfor %}
  </tr>
{%- endfor %}
</table>
jinja-filters.capitalize(s: str) str

値をキャピタライズします。最初の文字は大文字になり、それ以外の文字は小文字になります。

jinja-filters.center(value: str, width: int = 80) str

指定された幅のフィールド内で値を中央揃えします。

jinja-filters.default(value: V, default_value: V = '', boolean: bool = False) V

値が未定義の場合、渡されたデフォルト値を返し、それ以外の場合は変数の値を返します。

{{ my_variable|default('my_variable is not defined') }}

変数が定義されている場合、my_variableの値が出力され、それ以外の場合は'my_variable is not defined'が出力されます。falseと評価される変数でdefaultを使用する場合は、2番目のパラメータをtrueに設定する必要があります。

{{ ''|default('the string was empty', true) }}
変更ログ

バージョン2.11で変更されました:EnvironmentChainableUndefinedで設定できるようになりました。defaultフィルタを、チェーン内に未定義の値を含む可能性のある入れ子になった要素や属性でUndefinedErrorを取得せずに動作させることができます。

エイリアス:

d

jinja-filters.dictsort(value: Mapping[K, V], case_sensitive: bool = False, by: 'te.Literal["key", "value"]' = 'key', reverse: bool = False) List[Tuple[K, V]]

辞書をソートし、(キー、値)のペアを生成します。Pythonの辞書は、表示したい順序になっていない可能性があるため、最初にソートします。

{% for key, value in mydict|dictsort %}
    sort the dict by key, case insensitive

{% for key, value in mydict|dictsort(reverse=true) %}
    sort the dict by key, case insensitive, reverse order

{% for key, value in mydict|dictsort(true) %}
    sort the dict by key, case sensitive

{% for key, value in mydict|dictsort(false, 'value') %}
    sort the dict by value, case insensitive
jinja-filters.escape(value)

文字列内の&<>'"をHTMLセーフなシーケンスに置き換えます。HTMLで表示する可能性のあるこのような文字を含むテキストを表示する必要がある場合に使用します。

オブジェクトに__html__メソッドがある場合、そのメソッドが呼び出され、戻り値はすでにHTMLとして安全であるとみなされます。

パラメータ:

s – 文字列に変換してエスケープするオブジェクト。

戻り値:

エスケープされたテキストを含むMarkup文字列。

エイリアス:

e

jinja-filters.filesizeformat(value: str | float | int, binary: bool = False) str

値を「人間が読みやすい」ファイルサイズ(例:13 kB、4.1 MB、102 バイトなど)としてフォーマットします。デフォルトでは10進接頭辞(メガ、ギガなど)が使用されますが、2番目のパラメータをTrueに設定すると、2進接頭辞(メビ、ギビなど)が使用されます。

jinja-filters.first(seq: 't.Iterable[V]') 't.Union[V, Undefined]'

シーケンスの最初のアイテムを返します。

jinja-filters.float(value: Any, default: float = 0.0) float

値を浮動小数点数に変換します。変換に失敗した場合は0.0を返します。このデフォルト値は最初の引数で上書きできます。

jinja-filters.forceescape(value: 't.Union[str, HasHTML]') markupsafe.Markup

HTMLエスケープを強制します。これにより、変数が二重エスケープされる可能性があります。

jinja-filters.format(value: str, *args: Any, **kwargs: Any) str

string % valuesのように、与えられた値をprintfスタイルのフォーマット文字列に適用します。

{{ "%s, %s!"|format(greeting, name) }}
Hello, World!

ほとんどの場合、%演算子またはstr.format()を使用する方が便利で効率的です。

{{ "%s, %s!" % (greeting, name) }}
{{ "{}, {}!".format(greeting, name) }}
jinja-filters.groupby(value: 't.Iterable[V]', attribute: str | int, default: Any | None = None, case_sensitive: bool = False) 't.List[_GroupTuple]'

Pythonのitertools.groupby()を使用して、属性に基づいてオブジェクトのシーケンスをグループ化します。属性は、"address.city"のように、ネストされたアクセスに対してドット表記を使用できます。Pythonのgroupbyとは異なり、値は最初にソートされるため、各一意の値に対して1つのグループのみが返されます。

たとえば、city属性を持つUserオブジェクトのリストをグループでレンダリングできます。この例では、grouperはグループのcity値を参照します。

<ul>{% for city, items in users|groupby("city") %}
  <li>{{ city }}
    <ul>{% for user in items %}
      <li>{{ user.name }}
    {% endfor %}</ul>
  </li>
{% endfor %}</ul>

groupby(grouper, list)のnamedtupleを生成し、上記のタプルアンパックの代わりに使用できます。grouperは属性の値であり、listはその値を持つアイテムです。

<ul>{% for group in users|groupby("city") %}
  <li>{{ group.grouper }}: {{ group.list|join(", ") }}
{% endfor %}</ul>

リスト内のオブジェクトに指定された属性がない場合に使用するdefault値を指定できます。

<ul>{% for city, items in users|groupby("city", default="NY") %}
  <li>{{ city }}: {{ items|map(attribute="name")|join(", ") }}</li>
{% endfor %}</ul>

sort()フィルタと同様に、ソートとグループ化はデフォルトで大文字と小文字を区別しません。各グループのkeyはその値のグループの最初のアイテムの大文字と小文字になります。たとえば、ユーザーのリストに["CA", "NY", "ca"]という都市がある場合、「CA」グループには2つの値が含まれます。case_sensitive=Trueを渡すことで、これを無効にできます。

バージョン 3.1 で変更: case_sensitiveパラメータを追加しました。比較を行う他のフィルタと同様に、ソートとグループ化はデフォルトで大文字と小文字を区別しません。

変更ログ

バージョン 3.0 で変更: defaultパラメータを追加しました。

バージョン 2.6 で変更: 属性は、ネストされたアクセスに対してドット表記をサポートするようになりました。

jinja-filters.indent(s: str, width: int | str = 4, first: bool = False, blank: bool = False) str

各行を4つのスペースでインデントした文字列のコピーを返します。デフォルトでは、最初の行と空行はインデントされません。

パラメータ:
  • width – インデントするスペース数、または文字列。

  • first – 最初の行のインデントをスキップしません。

  • blank – 空行のインデントをスキップしません。

変更ログ

バージョン 3.0 で変更されました: widthは文字列にすることができます。

バージョン 2.10 で変更されました: デフォルトでは空行はインデントされません。

indentfirst引数をfirstに名前変更しました。

jinja-filters.int(value: Any, default: int = 0, base: int = 10) int

値を整数に変換します。変換に失敗した場合は`0`を返します。最初の引数でこのデフォルト値を上書きできます。2番目の引数でデフォルトの基数(10)も上書きできます。これは、2、8、16を基数とする0b、0o、0xなどの接頭辞を持つ入力を処理します。基数は10進数と文字列以外の値では無視されます。

jinja-filters.items(value: Mapping[K, V] | jinja2.runtime.Undefined) Iterator[Tuple[K, V]]

マッピングの`(キー, 値)`項目のイテレータを返します。

x|itemsx.items()と同じですが、xが未定義の場合、空のイテレータが返されます。

このフィルタは、`items()`メソッドをマッピング型に持たない他のプログラミング言語のJinja実装でテンプレートがレンダリングされると予想される場合に役立ちます。

<dl>
{% for key, value in my_dict|items %}
    <dt>{{ key }}
    <dd>{{ value }}
{% endfor %}
</dl>

バージョン 3.1 で追加されました。

jinja-filters.join(value: Iterable[Any], d: str = '', attribute: str | int | NoneType = None) str

シーケンス内の文字列を連結した文字列を返します。要素間のセパレータはデフォルトで空文字列ですが、オプションのパラメータで定義できます。

{{ [1, 2, 3]|join('|') }}
    -> 1|2|3

{{ [1, 2, 3]|join }}
    -> 123

オブジェクトの特定の属性を結合することも可能です。

{{ users|join(', ', attribute='username') }}
変更ログ

バージョン 2.6 で追加されました: attributeパラメータが追加されました。

jinja-filters.last(seq: 't.Reversible[V]') 't.Union[V, Undefined]'

シーケンスの最後の項目を返します。

注: ジェネレータでは機能しません。明示的にリストに変換する必要がある場合があります。

{{ data | selectattr('name', '==', 'Jinja') | list | last }}
jinja-filters.length(obj, /)

コンテナ内のアイテム数を返します。

エイリアス:

count

jinja-filters.list(value: 't.Iterable[V]') 't.List[V]'

値をリストに変換します。文字列だった場合、返されるリストは文字のリストになります。

jinja-filters.lower(s: str) str

値を小文字に変換します。

jinja-filters.map(value: Iterable[Any], *args: Any, **kwargs: Any) Iterable[Any]

オブジェクトのシーケンスにフィルタを適用するか、属性を検索します。これは、オブジェクトのリストを処理しているが、実際にはその特定の値のみに関心がある場合に役立ちます。

基本的な使い方は、属性へのマッピングです。ユーザのリストがあり、ユーザ名のリストのみに関心がある場合を考えてみましょう。

Users on this page: {{ users|map(attribute='username')|join(', ') }}

リスト内のオブジェクトに指定された属性がない場合に使用するdefault値を指定できます。

{{ users|map(attribute="username", default="Anonymous")|join(", ") }}

あるいは、フィルタの名前と引数をその後ろに渡すことで、フィルタを呼び出すこともできます。シーケンスにテキスト変換フィルタを適用する場合の良い例です。

Users on this page: {{ titles|map('lower')|join(', ') }}

次のようなジェネレータ式に似ています。

(u.username for u in users)
(getattr(u, "username", "Anonymous") for u in users)
(do_lower(x) for x in titles)
変更ログ

バージョン 2.11.0 で変更されました: defaultパラメータが追加されました。

バージョン 2.7 で追加されました。

jinja-filters.max(value: 't.Iterable[V]', case_sensitive: bool = False, attribute: str | int | NoneType = None) 't.Union[V, Undefined]'

シーケンスから最大のアイテムを返します。

{{ [1, 2, 3]|max }}
    -> 3
パラメータ:
  • case_sensitive – 大文字と小文字を区別して文字列を扱います。

  • attribute – この属性の最大値を持つオブジェクトを取得します。

jinja-filters.min(value: 't.Iterable[V]', case_sensitive: bool = False, attribute: str | int | NoneType = None) 't.Union[V, Undefined]'

シーケンスから最小のアイテムを返します。

{{ [1, 2, 3]|min }}
    -> 1
パラメータ:
  • case_sensitive – 大文字と小文字を区別して文字列を扱います。

  • attribute – この属性の最小値を持つオブジェクトを取得します。

jinja-filters.pprint(value: Any) str

変数を整形して出力します。デバッグに役立ちます。

jinja-filters.random(seq: 't.Sequence[V]') 't.Union[V, Undefined]'

シーケンスからランダムにアイテムを返します。

jinja-filters.reject(value: 't.Iterable[V]', *args: Any, **kwargs: Any) 't.Iterator[V]'

各オブジェクトにテストを適用し、テストに成功したオブジェクトを除外することで、オブジェクトのシーケンスをフィルタリングします。

テストが指定されていない場合、各オブジェクトはブール値として評価されます。

使用例

{{ numbers|reject("odd") }}

次のようなジェネレータ式に似ています。

(n for n in numbers if not test_odd(n))
変更ログ

バージョン 2.7 で追加されました。

jinja-filters.rejectattr(value: 't.Iterable[V]', *args: Any, **kwargs: Any) 't.Iterator[V]'

各オブジェクトの指定された属性にテストを適用し、テストに成功したオブジェクトを除外することで、オブジェクトのシーケンスをフィルタリングします。

テストが指定されていない場合、属性の値はブール値として評価されます。

{{ users|rejectattr("is_active") }}
{{ users|rejectattr("email", "none") }}

次のようなジェネレータ式に似ています。

(u for user in users if not user.is_active)
(u for user in users if not test_none(user.email))
変更ログ

バージョン 2.7 で追加されました。

jinja-filters.replace(s: str, old: str, new: str, count: int | None = None) str

部分文字列のすべての出現箇所を新しい文字列に置き換えた値のコピーを返します。最初の引数は置き換えられる部分文字列、2番目の引数は置換文字列です。オプションの3番目の引数countが指定されている場合、最初のcount個の出現箇所のみが置き換えられます。

{{ "Hello World"|replace("Hello", "Goodbye") }}
    -> Goodbye World

{{ "aaaaargh"|replace("a", "d'oh, ", 2) }}
    -> d'oh, d'oh, aaargh
jinja-filters.reverse(value: str | Iterable[V]) str | Iterable[V]

オブジェクトを反転するか、逆順で反復処理を行うイテレータを返します。

jinja-filters.round(value: float, precision: int = 0, method: 'te.Literal["common", "ceil", "floor"]' = 'common') float

数を指定された精度に丸めます。最初の引数は精度(デフォルトは0)、2番目の引数は丸め方法を指定します。

  • 'common' は、上方または下方に丸めます。

  • 'ceil' は常に上方へ丸めます。

  • 'floor' は常に下方へ丸めます。

メソッドを指定しない場合、'common' が使用されます。

{{ 42.55|round }}
    -> 43.0
{{ 42.55|round(1, 'floor') }}
    -> 42.5

精度を0に丸めた場合でも、浮動小数点数型が返されます。整数が必要な場合は、int を通してパイプ処理してください。

{{ 42.55|round|int }}
    -> 43
jinja-filters.safe(value: str) markupsafe.Markup

値を安全なものとしてマークします。つまり、自動エスケープが有効な環境では、この変数はエスケープされません。

jinja-filters.select(value: 't.Iterable[V]', *args: Any, **kwargs: Any) 't.Iterator[V]'

オブジェクトのシーケンスをフィルタリングします。各オブジェクトにテストを適用し、テストに成功したオブジェクトのみを選択します。

テストが指定されていない場合、各オブジェクトはブール値として評価されます。

使用例

{{ numbers|select("odd") }}
{{ numbers|select("odd") }}
{{ numbers|select("divisibleby", 3) }}
{{ numbers|select("lessthan", 42) }}
{{ strings|select("equalto", "mystring") }}

次のようなジェネレータ式に似ています。

(n for n in numbers if test_odd(n))
(n for n in numbers if test_divisibleby(n, 3))
変更ログ

バージョン 2.7 で追加されました。

jinja-filters.selectattr(value: 't.Iterable[V]', *args: Any, **kwargs: Any) 't.Iterator[V]'

オブジェクトのシーケンスをフィルタリングします。各オブジェクトの指定された属性にテストを適用し、テストに成功したオブジェクトのみを選択します。

テストが指定されていない場合、属性の値はブール値として評価されます。

使用例

{{ users|selectattr("is_active") }}
{{ users|selectattr("email", "none") }}

次のようなジェネレータ式に似ています。

(u for user in users if user.is_active)
(u for user in users if test_none(user.email))
変更ログ

バージョン 2.7 で追加されました。

jinja-filters.slice(value: 't.Collection[V]', slices: int, fill_with: 't.Optional[V]' = None) 't.Iterator[t.List[V]]'

イテレータをスライスし、それらのアイテムを含むリストのリストを返します。3つのulタグを含むdivを作成し、それらを列として表現する場合に役立ちます。

<div class="columnwrapper">
  {%- for column in items|slice(3) %}
    <ul class="column-{{ loop.index }}">
    {%- for item in column %}
      <li>{{ item }}</li>
    {%- endfor %}
    </ul>
  {%- endfor %}
</div>

第2引数を渡すと、最後の繰り返しで欠損値を埋めるために使用されます。

jinja-filters.sort(value: 't.Iterable[V]', reverse: bool = False, case_sensitive: bool = False, attribute: str | int | NoneType = None) 't.List[V]'

Pythonのsorted()を使用して、イテラブルをソートします。

{% for city in cities|sort %}
    ...
{% endfor %}
パラメータ:
  • **reverse** – 昇順ではなく降順でソートします。

  • **case_sensitive** – 文字列をソートする場合、大文字と小文字を分けてソートします。

  • **attribute** – オブジェクトまたは辞書をソートする場合、ソートする属性またはキーを指定します。「address.city」のようなドット表記を使用できます。「age,name」のような属性のリストも使用できます。

ソートは安定しています。等しいと比較される要素の相対的な順序は変更されません。これにより、異なる属性と順序でソートを連鎖させることが可能です。

{% for user in users|sort(attribute="name")
    |sort(reverse=true, attribute="age") %}
    ...
{% endfor %}

方向がすべての属性で同じである場合の連鎖のショートカットとして、コンマ区切りの属性リストを渡します。

{% for user in users|sort(attribute="age,name") %}
    ...
{% endfor %}
変更ログ

バージョン2.11.0で変更されました: attributeパラメータは、コンマ区切りの属性リスト(例:「age,name」)にすることができます。

バージョン2.6で変更されました: attributeパラメータが追加されました。

jinja-filters.string(value)

オブジェクトがまだ文字列でない場合は、文字列に変換します。Markup文字列は基本的な文字列に変換するのではなく保持されるため、安全であるとマークされ、再度エスケープされません。

>>> value = escape("<User 1>")
>>> value
Markup('&lt;User 1&gt;')
>>> escape(str(value))
Markup('&amp;lt;User 1&amp;gt;')
>>> escape(soft_str(value))
Markup('&lt;User 1&gt;')
jinja-filters.striptags(value: 't.Union[str, HasHTML]') str

SGML/XMLタグを取り除き、隣接する空白を1つのスペースに置き換えます。

jinja-filters.sum(iterable: 't.Iterable[V]', attribute: str | int | NoneType = None, start: V = 0) V

数値のシーケンスの合計とパラメータ「start」(デフォルトは0)の値を返します。シーケンスが空の場合は、startを返します。

特定の属性だけを合計することも可能です。

Total: {{ items|sum(attribute='price') }}
変更ログ

バージョン2.6で変更されました: attributeパラメータが追加され、属性の合計が可能になりました。startパラメータも右側に移動されました。

jinja-filters.title(s: str) str

値の大文字化されたバージョンを返します。つまり、単語はそれぞれ大文字で始まり、残りの文字は小文字になります。

jinja-filters.tojson(value: Any, indent: int | None = None) markupsafe.Markup

オブジェクトをJSON文字列にシリアライズし、HTMLでのレンダリングを安全にするマークを付けます。このフィルターはHTMLドキュメントでの使用のみに限定されます。

返される文字列は、HTMLドキュメントと<script>タグでのレンダリングが安全です。ただし、二重引用符で囲まれたHTML属性内では例外となります。単一引用符を使用するか、|forceescapeフィルターを使用してください。

パラメータ:
  • value – JSONにシリアライズするオブジェクト。

  • indent – 値を整形して表示するためにdumpsに渡されるindentパラメーター。

変更ログ

バージョン2.9で追加されました。

jinja-filters.trim(value: str, chars: str | None = None) str

先頭と末尾の文字(デフォルトでは空白)を取り除きます。

jinja-filters.truncate(s: str, length: int = 255, killwords: bool = False, end: str = '...', leeway: int | None = None) str

文字列の切り詰められたコピーを返します。長さは最初の引数で指定され、デフォルトは255です。2番目のパラメーターがtrueの場合、フィルターは指定された長さでテキストを切ります。それ以外の場合は、最後の単語を破棄します。テキストが実際を切り詰められた場合、省略記号("...")を追加します。"..."以外の省略記号を使用する場合は、3番目のパラメーターで指定できます。4番目のパラメーターで指定された許容範囲内でのみ長さを超える文字列は切り詰められません。

{{ "foo bar baz qux"|truncate(9) }}
    -> "foo..."
{{ "foo bar baz qux"|truncate(9, True) }}
    -> "foo ba..."
{{ "foo bar baz qux"|truncate(11) }}
    -> "foo bar baz qux"
{{ "foo bar baz qux"|truncate(11, False, '...', 0) }}
    -> "foo bar..."

新しいJinjaバージョンでのデフォルトの許容範囲は5であり、以前は0でしたが、グローバルに再構成できます。

jinja-filters.unique('t.Iterable[V]', case_sensitive: bool = False, attribute: str | int | NoneType = None) 't.Iterator[V]'

与えられた反復可能オブジェクトから一意のアイテムのリストを返します。

{{ ['foo', 'bar', 'foobar', 'FooBar']|unique|list }}
    -> ['foo', 'bar', 'foobar']

一意のアイテムは、フィルターに渡された反復可能オブジェクト内での最初の出現順に生成されます。

パラメータ:
  • case_sensitive – 大文字と小文字を区別して文字列を扱います。

  • attribute – この属性の一意の値を持つオブジェクトをフィルターします。

jinja-filters.upper(s: str) str

値を大文字に変換します。

jinja-filters.urlencode(value: str | Mapping[str, Any] | Iterable[Tuple[str, Any]]) str

UTF-8を使用して、URLパスまたはクエリで使用するためのデータを引用符で囲みます。

文字列が与えられた場合のurllib.parse.quote()、辞書または反復可能オブジェクトの場合のurllib.parse.urlencode()の基本的なラッパーです。

パラメータ:

value – 引用符で囲むデータ。文字列は直接引用符で囲まれます。(key, value)ペアの辞書または反復可能オブジェクトは、クエリ文字列として連結されます。

文字列が与えられた場合、「/」は引用符で囲まれません。HTTPサーバーはパス内で「/」と「%2F」を同等に扱います。引用符で囲まれたスラッシュが必要な場合は、|replace("/", "%2F")フィルターを使用してください。

変更ログ

バージョン 2.7 で追加されました。

jinja-filters.urlize(value: str, trim_url_limit: int | None = None, nofollow: bool = False, target: str | None = None, rel: str | None = None, extra_schemes: Iterable[str] | None = None) str

テキスト内のURLを、クリック可能なリンクに変換します。

状況によっては、リンクを認識できない場合があります。通常は、Markdownライブラリなどのより包括的なフォーマッタの方が適しています。

http://https://www.mailto:、およびメールアドレスに対応しています。末尾の句読点(ピリオド、コンマ、閉じ括弧)と先頭の句読点(開き括弧)を持つリンクは、句読点を除いて認識されます。ヘッダーフィールドを含むメールアドレスは認識されません(例:mailto:address@example.com?cc=copy@example.com)。

パラメータ:
  • **value** – リンクするURLを含む元のテキスト。

  • **trim_url_limit** – 表示されるURLの値をこの長さまで短縮します。

  • **nofollow** – リンクにrel=nofollow属性を追加します。

  • **target** – リンクにtarget属性を追加します。

  • **rel** – リンクにrel属性を追加します。

  • **extra_schemes** – デフォルトの動作に加えて、これらのスキームで始まるURLを認識します。デフォルトではenv.policies["urlize.extra_schemes"]になり、これは追加のスキームなしを意味します。

変更ログ

バージョン 3.0 で変更されました: extra_schemesパラメータが追加されました。

バージョン 3.0 で変更されました: スキームのないURLに対してhttps://リンクを生成するようになりました。

バージョン 3.0 で変更されました: 構文解析ルールが更新されました。mailto:スキームの有無にかかわらずメールアドレスを認識するようになりました。IPアドレスを検証します。より多くの場合において、括弧を無視します。

バージョン 2.8 で変更されました: targetパラメータが追加されました。

jinja-filters.wordcount(s: str) int

文字列内の単語数をカウントします。

jinja-filters.wordwrap(s: str, width: int = 79, break_long_words: bool = True, wrapstring: str | None = None, break_on_hyphens: bool = True) str

文字列を指定された幅に折り返します。既存の改行は、個別に折り返される段落として扱われます。

パラメータ:
  • **s** – 折り返す元のテキスト。

  • **width** – 折り返された行の最大長。

  • **break_long_words** – 単語がwidthよりも長い場合、行を跨いで分割します。

  • **break_on_hyphens** – 単語にハイフンが含まれる場合、行を跨いで分割される可能性があります。

  • **wrapstring** – 各折り返された行を結合する文字列。デフォルトはEnvironment.newline_sequenceです。

変更ログ

バージョン 2.11 で変更されました: 既存の改行は、個別に折り返される段落として扱われるようになりました。

バージョン 2.11 で変更されました: break_on_hyphensパラメータが追加されました。

バージョン 2.7 で変更されました: wrapstringパラメータが追加されました。

jinja-filters.xmlattr(d: Mapping[str, Any], autospace: bool = True) str

辞書の項目に基づいて、SGML/XML属性文字列を作成します。

**値**がnoneでもundefinedでもない場合、自動的にエスケープされます。これにより、信頼できないユーザー入力も安全に許可されます。

このフィルタの**キー**としてユーザー入力を使用しないでください。キーにスペース、スラッシュ/、大なり記号>、または等号=が含まれる場合、ValueErrorが発生して失敗します。いずれにしても、このフィルタのキーとしてユーザー入力を使用することは避け、事前に別途検証する必要があります。

<ul{{ {'class': 'my_list', 'missing': none,
        'id': 'list-%d'|format(variable)}|xmlattr }}>
...
</ul>

次のような結果になります。

<ul class="my_list" id="list-42">
...
</ul>

ご覧のように、2番目のパラメータがfalseでない限り、フィルタが何かを返した場合、項目の前にスペースが自動的に追加されます。

バージョン 3.1.4 で変更: / (スラッシュ)、> (大于号)、または= (等号)を含むキーは許可されません。

バージョン 3.1.3 で変更: スペースを含むキーは許可されません。

組み込みテストのリスト

boolean()

even()

in()

mapping()

sequence()

callable()

false()

integer()

ne()

string()

defined()

filter()

iterable()

none()

test()

divisibleby()

float()

le()

number()

true()

eq()

ge()

lower()

odd()

undefined()

escaped()

gt()

lt()

sameas()

upper()

jinja-tests.boolean(value: Any) bool

オブジェクトがブール値である場合、true を返します。

変更ログ

バージョン 2.11 で追加。

jinja-tests.callable(obj, /)

オブジェクトが呼び出し可能かどうか(つまり、何らかの関数であるか)を返します。

クラスは呼び出し可能であり、`__call__()` メソッドを持つクラスのインスタンスも呼び出し可能です。

jinja-tests.defined(value: Any) bool

変数が定義されている場合、true を返します。

{% if variable is defined %}
    value of variable: {{ variable }}
{% else %}
    variable is not defined
{% endif %}

未定義の変数を設定する簡単な方法については、default() フィルターを参照してください。

jinja-tests.divisibleby(value: int, num: int) bool

変数が数値で割り切れるかどうかをチェックします。

jinja-tests.eq(a, b, /)

a == b と同じです。

エイリアス:

==equalto

jinja-tests.escaped(value: Any) bool

値がエスケープされているかどうかをチェックします。

jinja-tests.even(value: int) bool

変数が偶数の場合、true を返します。

jinja-tests.false(value: Any) bool

オブジェクトが False の場合、true を返します。

変更ログ

バージョン 2.11 で追加。

jinja-tests.filter(value: str) bool

フィルターが名前で存在するかどうかをチェックします。フィルターがオプションで利用できる場合に便利です。

{% if 'markdown' is filter %}
    {{ value | markdown }}
{% else %}
    {{ value }}
{% endif %}
変更ログ

バージョン 3.0 で追加。

jinja-tests.float(value: Any) bool

オブジェクトが浮動小数点数の場合、true を返します。

変更ログ

バージョン 2.11 で追加。

jinja-tests.ge(a, b, /)

a >= b と同じです。

エイリアス:

>=

jinja-tests.gt(a, b, /)

a > b と同じです。

エイリアス:

>greaterthan

jinja-tests.in(value: Any, seq: Container[Any]) bool

value が seq に含まれているかどうかをチェックします。

変更ログ

バージョン 2.10 で追加。

jinja-tests.integer(value: Any) bool

オブジェクトが整数の場合、true を返します。

変更ログ

バージョン 2.11 で追加。

jinja-tests.iterable(value: Any) bool

オブジェクトを反復処理できるかどうかをチェックします。

jinja-tests.le(a, b, /)

a <= b と同じです。

エイリアス:

<=

jinja-tests.lower(value: str) bool

変数が小文字の場合、true を返します。

jinja-tests.lt(a, b, /)

a < b と同じです。

エイリアス:

<lessthan

jinja-tests.mapping(value: Any) bool

オブジェクトがマッピング(辞書など)の場合、true を返します。

変更ログ

バージョン 2.6 で追加。

jinja-tests.ne(a, b, /)

a != b と同じです。

エイリアス:

!=

jinja-tests.none(value: Any) bool

変数がNoneの場合、trueを返します。

jinja-tests.number(value: Any) bool

変数が数値の場合、trueを返します。

jinja-tests.odd(value: int) bool

変数が奇数の場合、trueを返します。

jinja-tests.sameas(value: Any, other: Any) bool

オブジェクトが別のオブジェクトと同じメモリアドレスを指しているかどうかを確認します。

{% if foo.attribute is sameas false %}
    the foo attribute really is the `False` singleton
{% endif %}
jinja-tests.sequence(value: Any) bool

変数がシーケンスの場合、trueを返します。シーケンスとは、反復可能な変数です。

jinja-tests.string(value: Any) bool

オブジェクトが文字列の場合、trueを返します。

jinja-tests.test(value: str) bool

名前でテストが存在するかどうかを確認します。テストがオプションで利用できる場合に便利です。

{% if 'loud' is test %}
    {% if value is loud %}
        {{ value|upper }}
    {% else %}
        {{ value|lower }}
    {% endif %}
{% else %}
    {{ value }}
{% endif %}
変更ログ

バージョン 3.0 で追加。

jinja-tests.true(value: Any) bool

オブジェクトがTrueの場合、trueを返します。

変更ログ

バージョン 2.11 で追加。

jinja-tests.undefined(value: Any) bool

defined() と逆の動作をします。

jinja-tests.upper(value: str) bool

変数が大文字の場合、trueを返します。

グローバル関数一覧

以下の関数は、デフォルトでグローバルスコープで使用できます。

jinja-globals.range([start, ]stop[, step])

整数の算術級数を格納したリストを返します。range(i, j)[i, i+1, i+2, ..., j-1] を返します。`start` (!) のデフォルトは 0 です。`step` が指定されている場合、増分(または減分)を指定します。たとえば、range(4)range(0, 4, 1)[0, 1, 2, 3] を返します。終点は省略されます!これらは、4つの要素のリストの有効なインデックスです。

これは、テンプレートブロックを複数回繰り返すのに役立ちます(例:リストを埋める)。リストに7人のユーザーがいるとします。しかし、CSSで高さを強制するために3つの空のアイテムをレンダリングしたいとします。

<ul>
{% for user in users %}
    <li>{{ user.username }}</li>
{% endfor %}
{% for number in range(10 - users|count) %}
    <li class="empty"><span>...</span></li>
{% endfor %}
</ul>
jinja-globals.lipsum(n=5, html=True, min=20, max=100)

テンプレートにダミーテキスト(Lorem ipsum)を生成します。デフォルトでは、各段落が20~100語のHTMLが5段落生成されます。`html`がFalseの場合、通常のテキストが返されます。これは、レイアウトテストのための単純なコンテンツを生成するのに役立ちます。

jinja-globals.dict(\**items)

辞書リテラルに代わる便利な方法です。{'foo': 'bar'}dict(foo='bar') と同じです。

class jinja-globals.cycler(\*items)

値を順番に生成し、終わりに達したら最初から繰り返します。

loop.cycle と似ていますが、ループの外側または複数のループで使用できます。たとえば、フォルダとファイルのリストを交互に「奇数」と「偶数」のクラスを与えてレンダリングします。

{% set row_class = cycler("odd", "even") %}
<ul class="browser">
{% for folder in folders %}
  <li class="folder {{ row_class.next() }}">{{ folder }}
{% endfor %}
{% for file in files %}
  <li class="file {{ row_class.next() }}">{{ file }}
{% endfor %}
</ul>
パラメータ:

items – 各位置引数は、サイクルごとに指定された順序で生成されます。

変更ログ

バージョン2.1で追加されました。

property current

現在のアイテムを返します。次回next()が呼び出された際に返されるアイテムと同じです。

next()

現在のアイテムを返し、currentを次のアイテムに進めます。

reset()

現在のアイテムを最初のアイテムにリセットします。

class jinja-globals.joiner(sep=', ')

複数のセクションを「結合」するために使用できる小さなヘルパーです。ジョイナーは文字列を受け取り、最初に呼び出された時(空文字列を返す場合)を除いて、その文字列を返すたびに返します。これを使用して、ものを結合できます。

{% set pipe = joiner("|") %}
{% if categories %} {{ pipe() }}
    Categories: {{ categories|join(", ") }}
{% endif %}
{% if author %} {{ pipe() }}
    Author: {{ author() }}
{% endif %}
{% if can_edit %} {{ pipe() }}
    <a href="?action=edit">Edit</a>
{% endif %}
変更ログ

バージョン2.1で追加されました。

class jinja-globals.namespace(...)

{% set %}タグを使用して属性の代入を許可する新しいコンテナを作成します。

{% set ns = namespace() %}
{% set ns.foo = 'bar' %}

これの主な目的は、ループ本体内の値を外側のスコープに持ち運ぶことを許可することです。初期値は、辞書、キーワード引数、またはその両方として提供できます(Pythonのdictコンストラクタと同じ動作)。

{% set ns = namespace(found=false) %}
{% for item in items %}
    {% if item.check_something() %}
        {% set ns.found = true %}
    {% endif %}
    * {{ item.title }}
{% endfor %}
Found item having something: {{ ns.found }}
変更ログ

バージョン 2.10 で追加。

拡張機能

次のセクションでは、アプリケーションによって有効にできる組み込みのJinja拡張機能について説明します。アプリケーションは、このドキュメントで説明されていないさらに拡張機能を提供することもできます。その場合、これらの拡張機能を説明する別のドキュメントが必要です。

i18n

i18n拡張機能が有効になっている場合、テンプレート内のテキストを翻訳可能としてマークできます。transブロックを使用して、セクションを翻訳可能としてマークします。

{% trans %}Hello, {{ user }}!{% endtrans %}

ブロック内では、ステートメントは許可されず、テキストと単純な変数タグのみが許可されます。

変数タグは名前のみで、属性アクセス、フィルタ、その他の式にはできません。式を使用するには、ブロック内で使用するためにtransタグで名前をバインドします。

{% trans user=user.username %}Hello, {{ user }}!{% endtrans %}

複数の式をバインドするには、それぞれをコンマ(,)で区切ります。

{% trans book_title=book.title, author=author.name %}
This is {{ book_title }} by {{ author }}
{% endtrans %}

複数形にするには、pluralizeタグで区切った単数形と複数形の両方を指定します。

{% trans count=list|length %}
There is {{ count }} {{ name }} object.
{% pluralize %}
There are {{ count }} {{ name }} objects.
{% endtrans %}

デフォルトでは、ブロック内の最初の変数が単数形と複数形を使用するかどうかを決定するために使用されます。それが正しくない場合は、pluralizeのパラメータとして複数形に使用される変数を指定します。

{% trans ..., user_count=users|length %}...
{% pluralize user_count %}...{% endtrans %}

テキストのブロックを翻訳する場合、空白と改行は、読みづらいエラーが発生しやすい翻訳文字列になります。これを回避するために、transブロックはトリミング済みとしてマークできます。これにより、すべての改行と改行を取り囲む空白が1つのスペースに置き換えられ、先頭と末尾の空白が削除されます。

{% trans trimmed book_title=book.title %}
    This is {{ book_title }}.
    You should read it!
{% endtrans %}

これにより、翻訳ファイルにThis is %(book_title)s. You should read it!が出力されます。

トリミングがグローバルに有効になっている場合、notrimmed修飾子を使用してブロックに対して無効にすることができます。

変更ログ

バージョン2.10で追加されました:trimmedおよびnotrimmed修飾子が追加されました。

翻訳がメッセージが表示されるコンテキストに依存する場合は、pgettextおよびnpgettext関数は、適切な翻訳を選択するために使用されるcontext文字列を最初の引数として受け取ります。{% trans %}タグでコンテキストを指定するには、transの後の最初のトークンとして文字列を指定します。

{% trans "fruit" %}apple{% endtrans %}
{% trans "fruit" trimmed count -%}
    1 apple
{%- pluralize -%}
    {{ count }} apples
{%- endtrans %}

バージョン3.1で追加されました:pgettextnpgettextを使用するために、transタグにコンテキストを渡すことができます。

これらの関数を使用して、式内の文字列を翻訳できます。

  • _(message)gettextのエイリアスです。

  • gettext(message):メッセージを翻訳します。

  • ngettext(singluar, plural, n):カウント変数に基づいて、単数形または複数形のメッセージを翻訳します。

  • pgettext(context, message)gettext()に似ていますが、コンテキスト文字列に基づいて翻訳を選択します。

  • npgettext(context, singular, plural, n)npgettext()に似ていますが、コンテキスト文字列に基づいて翻訳を選択します。

翻訳された文字列を次のように出力できます。

{{ _("Hello, World!") }}

プレースホルダーを使用するには、formatフィルタを使用します。

{{ _("Hello, %(user)s!")|format(user=user.username) }}

他の言語では同じ順番で単語を使用しない可能性があるため、常にformatにキーワード引数を使用してください。

新しいスタイルのGettext呼び出しが有効になっている場合、プレースホルダーの使用が容易になります。formatフィルタを使用する代わりに、gettext呼び出しにフォーマットが含まれます。

{{ gettext('Hello World!') }}
{{ gettext('Hello %(name)s!', name='World') }}
{{ ngettext('%(num)d apple', '%(num)d apples', apples|count) }}

ngettext関数のフォーマット文字列には、指定されたパラメータに加えて、numパラメータとしてカウントが自動的に渡されます。

式ステートメント

式ステートメント拡張機能がロードされている場合、通常の変数式({{ ... }})とまったく同じように機能するdoというタグが使用できます。ただし、何も出力しません。これは、リストの変更に使用できます。

{% do navigation.append('a string') %}

ループ制御

アプリケーションでループ制御を有効にすると、ループでbreakcontinueを使用できます。breakに到達すると、ループは終了します。continueに到達すると、処理が停止し、次の反復が続行されます。

これは、2番目のアイテムをスキップするループです。

{% for user in users %}
    {%- if loop.index is even %}{% continue %}{% endif %}
    ...
{% endfor %}

同様に、10回目の反復後に処理を停止するループです。

{% for user in users %}
    {%- if loop.index >= 10 %}{% break %}{% endif %}
{%- endfor %}

loop.indexは1から始まり、loop.index0は0から始まります(参照:For)。

デバッグステートメント

デバッグ拡張機能が有効になっている場合、現在のコンテキストと使用可能なフィルタとテストをダンプする{% debug %}タグが使用できます。これは、デバッガーを設定せずにテンプレートで使用できるものを確認するのに役立ちます。

<pre>{% debug %}</pre>
{'context': {'cycler': <class 'jinja2.utils.Cycler'>,
             ...,
             'namespace': <class 'jinja2.utils.Namespace'>},
 'filters': ['abs', 'attr', 'batch', 'capitalize', 'center', 'count', 'd',
             ..., 'urlencode', 'urlize', 'wordcount', 'wordwrap', 'xmlattr'],
 'tests': ['!=', '<', '<=', '==', '>', '>=', 'callable', 'defined',
           ..., 'odd', 'sameas', 'sequence', 'string', 'undefined', 'upper']}

Withステートメント

変更ログ

バージョン2.3で追加されました。

Withステートメントを使用すると、新しい内部スコープを作成できます。このスコープ内で設定された変数は、スコープの外からは見えません。

Withの概要

{% with %}
    {% set foo = 42 %}
    {{ foo }}           foo is 42 here
{% endwith %}
foo is not visible here any longer

スコープの先頭に変数を設定することが一般的であるため、withステートメント内でそれを行うことができます。次の2つの例は同等です。

{% with foo = 42 %}
    {{ foo }}
{% endwith %}

{% with %}
    {% set foo = 42 %}
    {{ foo }}
{% endwith %}

ここでスコープに関する重要な注意事項。2.9より前のJinjaバージョンでは、ある変数を別の変数に参照する動作に意図しない結果がありました。特に、ある変数は、同じwithブロックの開始ステートメントで定義された別の変数を参照できます。これは、クリーンアップされたスコープ動作に問題を引き起こし、それ以来改善されています。特に新しいJinjaバージョンでは、次のコードは常にwithブロックの外側の変数aを参照します。

{% with a={}, b=a.attribute %}...{% endwith %}

以前のJinjaバージョンでは、b属性は最初の属性の結果を参照していました。この動作に依存する場合は、setタグを使用して書き直すことができます。

{% with a={} %}
    {% set b = a.attribute %}
{% endwith %}

拡張機能

以前のバージョンのJinja(2.9より前)では、拡張機能を使用してこの機能を有効にする必要がありました。現在はデフォルトで有効になっています。

自動エスケープのオーバーライド

変更ログ

バージョン2.4で追加されました。

必要に応じて、テンプレート内から自動エスケープを有効および無効にすることができます。

{% autoescape true %}
    Autoescaping is active within this block
{% endautoescape %}

{% autoescape false %}
    Autoescaping is inactive within this block
{% endautoescape %}

endautoescapeの後、動作は以前の状態に戻ります。

拡張機能

以前のバージョンのJinja(2.9より前)では、拡張機能を使用してこの機能を有効にする必要がありました。現在はデフォルトで有効になっています。