他のテンプレートエンジンからの切り替え—Jinjaドキュメント
他のテンプレートエンジンからの切り替え
過去に別のテンプレートエンジンを使用したことがあり、Jinjaに切り替えたい場合は、Python用のいくつかの一般的な類似のテキストテンプレートエンジン間の基本的な構文およびセマンティックの変更を示す小さなガイドがあります。
ジンジャ1
Jinja 2は、APIの使用法とテンプレート構文の点でJinja1とほとんど互換性があります。 Jinja 1と2の違いは、次のリストで説明されています。
API
- ローダー
- Jinja2は別のローダーAPIを使用します。 テンプレートの内部表現が変更されたため、memcachedなどの外部キャッシュシステムはサポートされなくなりました。 テンプレートによって消費されるメモリは現在、通常のPythonモジュールと同等であり、外部キャッシュは何の利点もありません。 過去にカスタムローダーを使用したことがある場合は、新しいローダーAPI をご覧ください。
- 文字列からテンプレートをロードする
- 以前は、 jinja.from_string を使用して、デフォルトの環境構成で文字列からテンプレートを生成することが可能でした。 Jinja 2は、同じことを行うために使用できる
Template
クラスを提供しますが、オプションの追加構成があります。 - 自動Unicode変換
- Jinja 1は、特定のエンコーディングのバイトをUnicodeオブジェクトに自動変換しました。 ほとんどのライブラリは通常のPythonASCIIバイトからUnicodeへの変換を使用しているため、この変換は一貫性がなかったため、実装されなくなりました。 Jinja 2 を搭載したアプリケーションは、どこでも内部でユニコードを使用するか、Jinja2がユニコード文字列のみを渡すようにする必要があります。
- i18n
- Jinja 1は、国際化のためにカスタムトランスレータを使用しました。 i18nはJinja2拡張機能として利用可能になり、よりシンプルでgettextに適したインターフェースを使用し、babelをサポートしています。 詳細については、 i18n拡張機能を参照してください。
- 内部メソッド
- Jinja 1は、 call_function 、 get_attribute など、環境オブジェクトのいくつかの内部メソッドを公開しました。 それらは内部メソッドとしてマークされていましたが、それらをオーバーライドすることが可能でした。 Jinja2には同等のメソッドがありません。
- サンドボックス
- Jinja1はデフォルトでサンドボックスモードを実行していました。 実際にその機能を使用しているアプリケーションはほとんどないため、Jinja2ではオプションになりました。 サンドボックス実行の詳細については、
SandboxedEnvironment
を参照してください。 - コンテクスト
- Jinja 1には、環境に渡される変数のストレージとしてスタックコンテキストがありました。 Jinja 2にも同様のオブジェクトが存在しますが、変更は許可されておらず、シングルトンでもありません。 継承は動的であるため、テンプレートの評価中に複数のコンテキストオブジェクトが存在する可能性があります。
- フィルタとテスト
- フィルタとテストは現在、通常の機能です。 不要になり、ファクトリ関数を使用できるようになりました。
テンプレート
Jinja2の構文はJinja1とほぼ同じです。 違いは、マクロでは引数リストを括弧で囲む必要があることです。
さらに、Jinja 2では動的継承が可能になり、動的インクルードが可能になりました。 古いヘルパー関数 rendertemplate はなくなり、代わりに include を使用できます。 新しい import タグが使用されるため、インポートマクロと変数割り当てが含まれなくなりました。 この概念は、 Import のドキュメントで説明されています。
for タグで別の小さな変更が発生しました。 特別なループ変数には parent 属性がありません。代わりに、ループを自分でエイリアスする必要があります。 詳細については、親ループへのアクセスを参照してください。
Django
以前にDjangoテンプレートを使用したことがある場合は、Jinjaをよく知っているはずです。 実際、ほとんどの構文要素は同じように見え、同じように機能します。
ただし、Jinjaは、ドキュメントで説明されている構文要素をさらにいくつか提供しており、動作が少し異なるものもあります。
このセクションでは、テンプレートの変更について説明します。 APIは根本的に異なるため、ここでは取り上げません。
メソッド呼び出し
Djangoでは、メソッド呼び出しは暗黙的に機能しますが、Jinjaでは明示的なPython構文が必要です。 したがって、このDjangoコードは次のとおりです。
{% for page in user.get_created_pages %}
...
{% endfor %}
…ジンジャでは次のようになります。
{% for page in user.get_created_pages() %}
...
{% endfor %}
これにより、Djangoでは不可能な変数をメソッドに渡すことができます。 この構文はマクロにも使用されます。
フィルタ引数
Jinjaは、フィルターに複数の引数を提供します。 また、引数の受け渡しの構文も異なります。 Djangoでは次のようなテンプレート:
{{ items|join:", " }}
ジンジャでは次のようになります。
{{ items|join(', ') }}
これはもう少し冗長ですが、変数を含むさまざまなタイプの引数と、複数の引数を使用できます。
テスト
フィルタに加えて、is演算子を使用して実行できるテストもあります。 ここではいくつかの例を示します。
{% if user.user_id is odd %}
{{ user.username|e }} is odd
{% else %}
hmm. {{ user.username|e }} looks pretty normal
{% endif %}
ループ
forループはDjangoと非常によく似ていますが、特にループコンテキストのJinja特殊変数は、Djangoのように forloop ではなく、 loop と呼ばれます。
さらに、Django empty 引数は、Jinjaでは else と呼ばれます。 たとえば、Djangoテンプレートは次のとおりです。
{% for item in items %}
{{ item }}
{% empty %}
No items!
{% endfor %}
…ジンジャでは次のようになります。
{% for item in items %}
{{ item }}
{% else %}
No items!
{% endfor %}
サイクル
{% cycle %}
タグはJinjaには存在しません。 ただし、ループコンテキストの特殊変数で 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 %}
{% cycle ... as variable %}
に相当するものはありません。
マコ
これまでにMakoを使用していて、Jinjaに切り替えたい場合は、JinjaをMakoのように構成できます。
env = Environment('<%', '%>', '${', '}', '<%doc>', '</%doc>', '%', '##')
そのように構成された環境では、JinjaはMakoテンプレートの小さなサブセットを解釈できるはずです。 Jinjaは埋め込みPythonコードをサポートしていないため、テンプレートから移動する必要があります。 def(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 %>