テンプレート Templates

Flaskは自身のテンプレート・エンジンとしてJinja2を活用します。違うテンプレート・エンジンを使うことも当然自由ですが、それでもFlask自体を実行するためにJinja2をインストールする必要があります。この要件は、豊富なFlask拡張を有効にするために必要になります。Flask拡張は用意されているJinja2へ依存したものにできます。 Flask leverages Jinja2 as its template engine. You are obviously free to use a different template engine, but you still have to install Jinja2 to run Flask itself. This requirement is necessary to enable rich extensions. An extension can depend on Jinja2 being present.

このセクションが与えるのは、どのようにJinja2がFlaskへ統合されているかについての手早いイントロダクションだけです。テンプレート・エンジンの文法自体の情報について知りたい場合は、さらなる情報を公式のJinja2テンプレートのドキュメントを確認してください。 This section only gives a very quick introduction into how Jinja2 is integrated into Flask. If you want information on the template engine's syntax itself, head over to the official `Jinja2 Template Documentation <http://jinja.pocoo.org/docs/templates/>`_ for more information.

Jinjaの準備 Jinja Setup

カスタマイズされてない限り、Jinja2はFlaskによって以下のように設定されます: Unless customized, Jinja2 is configured by Flask as follows:

  • render_template()を使うとき、autoescaping(自動エスケープ)は.xhmlだけではなく.html, .htm, .xmlで終わる全てのテンプレートで有効になります。 autoescaping is enabled for all templates ending in ``.html``, ``.htm``, ``.xml`` as well as ``.xhtml`` when using :func:`~flask.templating.render_template`.

  • render_template_string()を使うとき、autoescaping(自動エスケープ)はすべての文字列で有効になります。 autoescaping is enabled for all strings when using :func:`~flask.templating.render_template_string`.

  • {% autoescape %}タグを使って、テンプレートはautoescaping(自動エスケープ)を有効にするかどうか意図的に切り替えられます。 a template has the ability to opt in/out autoescaping with the ``{% autoescape %}`` tag.

  • 標準設定で存在している値に追加して、FlaskはJinja2のcontextへ、いくつかのグローバルな(訳注: テンプレートのどこからでも使用可能な)関数とヘルパーを挿入します。 Flask inserts a couple of global functions and helpers into the Jinja2 context, additionally to the values that are present by default.

標準のコンテキスト(Standard Context) Standard Context

以下のグローバル変数は標準設定で、Jinja2テンプレートの中で利用可能です: The following global variables are available within Jinja2 templates by default:

config

その時点の設定オブジェクト(flask.Flask.config The current configuration object (:data:`flask.config`)

Changelog

バージョン 0.10 で変更: 今ではこれは、たとえimportされたテンプレートの中でも使用可能です。

バージョン 0.6 で追加.

request

その時点のrequestオブジェクト(flask.request)。テンプレートが活動中(active)のrequest contextの外側で変換(render)された場合、この変数は使用できません。 The current request object (:class:`flask.request`). This variable is unavailable if the template was rendered without an active request context.

session

その時点のsessionオブジェクト(flask.session)。てんぷれーとが活動中(active)のrequest contextなしで変換(render)された場合、この変数は使用できません。 The current session object (:class:`flask.session`). This variable is unavailable if the template was rendered without an active request context.

g

グローバル変数用にrequestに結び付けられたオブジェクト(flask.g)。活動中(active)のrequest contextなしで変換(render)された場合、この変数は使用できません。 The request-bound object for global variables (:data:`flask.g`). This variable is unavailable if the template was rendered without an active request context.

url_for()

flask.url_for()関数。 The :func:`flask.url_for` function.

get_flashed_messages()

flask.get_flashed_messages()関数。 The :func:`flask.get_flashed_messages` function.

Jinjaコンテキストの振る舞い(The Jinja Context Behavior) The Jinja Context Behavior

これらの変数は、グローバル変数ではない変数のcontextへ追加されます。その違いは、標準設定ではこれらの変数はimportされたテンプレートのcontextの中では見えなくなることです。その理由の一部は性能面のためであり、一部は物事を明示的に保つためです。 These variables are added to the context of variables, they are not global variables. The difference is that by default these will not show up in the context of imported templates. This is partially caused by performance considerations, partially to keep things explicit.

これはあなたにとってどのような意味があるのでしょうか?もしimportしたい、requestオブジェクトへのアクセスが必要なマクロがある場合、以下の2つの可能性があります: What does this mean for you? If you have a macro you want to import, that needs to access the request object you have two possibilities:

  1. 明示的に、requestをマクロへパラメータとして渡すか、またはrequestの関心のある属性を渡します。 you explicitly pass the request to the macro as parameter, or the attribute of the request object you are interested in.

  2. 「with context」でマクロをimportします。 you import the macro "with context".

contextを使ったimportは以下のようになります: Importing with context looks like this:

{% from '_helpers.html' import my_macro with context %}

標準のフィルタ(Standard Filters) Standard Filters

Jinja2自身によって提供されるフィルタに加えて、Flaskは以下のJinja2フィルタを提供します: Flask provides the following Jinja2 filters in addition to the filters provided by Jinja2 itself:

tojson()

この関数は与えられたオブジェクトをJSON表現へ変換します。これは、例えば、実行中にJavaScriptを生成しようと試みるときにとても役立ちます。 This function converts the given object into JSON representation. This is for example very helpful if you try to generate JavaScript on the fly.

<script type=text/javascript>
    doSomethingWith({{ user.username|tojson }});
</script>

|tojsonの出力は一重引用符で囲まれたHTML属性の中で使っても安全です: It is also safe to use the output of `|tojson` in a *single-quoted* HTML attribute:

<button onclick='doSomethingWith({{ user.username|tojson }})'>
    Click me
</button>

0.10.以前のFlaskのバージョンでは、scriptの内側で|tojsonの出力を使用する場合、|safeを使ってエスケープを確実に無効にするよう注意してください。Flaskの0.10以上では、これは自動的に起こります。 Note that in versions of Flask prior to 0.10, if using the output of ``|tojson`` inside ``script``, make sure to disable escaping with ``|safe``. In Flask 0.10 and above, this happens automatically.

自動エスケープの制御(Controlling Autoescaping) Controlling Autoescaping

自動エスケープは、特別な文字を自動的にエスケープするというコンセプトです。HTML(またはXML、さらにXHTML)の観点から、'だけでなく、&, >, <, "も特別な文字になります。これらの文字はドキュメントの中で独自の特別な意味を持つため、テキストとして使用したい場合は「entities」と呼ばれるものでそれらを置き換える必要があります。そうしないと、それらの文字をテキストで使えないためにユーザをいらだたせるだけでなく、セキュリティ上の問題にまで至る可能性もあります。(クロスサイトスクリプティング(Cross-Site Scripting)(XSS)を参照) Autoescaping is the concept of automatically escaping special characters for you. Special characters in the sense of HTML (or XML, and thus XHTML) are ``&``, ``>``, ``<``, ``"`` as well as ``'``. Because these characters carry specific meanings in documents on their own you have to replace them by so called "entities" if you want to use them for text. Not doing so would not only cause user frustration by the inability to use these characters in text, but can also lead to security problems. (see :ref:`xss`)

しかしながら、ときどき、テンプレートの中で自動エスケープを無効にすることが必要になります。例えば、markdownからHTMLへのコンバータのような、安全なHTMLを生成するシステムからくるときに、HTMLをページの中へ明示的に挿入したい場合には、そのケースに該当する可能性があります。 Sometimes however you will need to disable autoescaping in templates. This can be the case if you want to explicitly inject HTML into pages, for example if they come from a system that generates secure HTML like a markdown to HTML converter.

これを達成する3つのやり方があります: There are three ways to accomplish that:

  • Pythonコードの中で、HTML文字列をMarkupオブジェクトの中で囲んでから、テンプレートへそれを渡します。これは概して推奨されるやり方です。 In the Python code, wrap the HTML string in a :class:`~flask.Markup` object before passing it to the template. This is in general the recommended way.

  • テンプレートの中で、文字列を安全なHTMLとして明示的に印づけるために|safeフィルタを使います({{ myvariable|safe }})。 Inside the template, use the ``|safe`` filter to explicitly mark a string as safe HTML (``{{ myvariable|safe }}``)

  • 一時的に自動エスケープのシステムを完全に無効にします。 Temporarily disable the autoescape system altogether.

テンプレートの中で自動エスケープを無効にするには、{% autoescape %}ブロックを使用できます: To disable the autoescape system in templates, you can use the ``{% autoescape %}`` block:

{% autoescape false %}
    <p>autoescaping is disabled here
    <p>{{ will_not_be_escaped }}
{% endautoescape %}

これを行うときはいつでも、このブロック内で使用する変数について十分に注意するようお願いします。 Whenever you do this, please be very cautious about the variables you are using in this block.

フィルタの登録 Registering Filters

自分独自のフィルタをJinja2に登録したい場合、2つのやり方があります。アプリケーションのjinja_envへ手作業で押し入れるか、またはtemplate_filter()デコレータを使用します。 If you want to register your own filters in Jinja2 you have two ways to do that. You can either put them by hand into the :attr:`~flask.Flask.jinja_env` of the application or use the :meth:`~flask.Flask.template_filter` decorator.

以下の2つの例は同様に機能し、どちらもオブジェクトを逆順にします(訳注:文字列・配列・リストなどで順番を反対にします): The two following examples work the same and both reverse an object::

@app.template_filter('reverse')
def reverse_filter(s):
    return s[::-1]

def reverse_filter(s):
    return s[::-1]
app.jinja_env.filters['reverse'] = reverse_filter

デコレータのケースでは、フィルタ名として関数名を使いたい場合は、引数は必須ではありません。一度登録されると、Jinja2の組込みのフィルタと同じやり方で、自分のテンプレートの中でフィルタを使うことができ、例えばmylistと呼ばれるPythonのlistがcontextにあるときは、以下のように使えます: In case of the decorator the argument is optional if you want to use the function name as name of the filter. Once registered, you can use the filter in your templates in the same way as Jinja2's builtin filters, for example if you have a Python list in context called `mylist`::

{% for x in mylist | reverse %}
{% endfor %}

コンテキスト処理装置(Context Processors) Context Processors

テンプレートのcontextへ自動的に新しい変数を挿入するために、Flaskにはcontext processors(コンテキスト処理装置)が存在します。context processorsはテンプレートが変換(render)される前に走り、テンプレートのcontextへ新しい値を挿入する能力を持ちます。context processorはdictionaryを返す関数です。このdictionaryのキーと値は、app中のすべてのテンプレートで、テンプレートのcontextに併合(merge)されます: To inject new variables automatically into the context of a template, context processors exist in Flask. Context processors run before the template is rendered and have the ability to inject new values into the template context. A context processor is a function that returns a dictionary. The keys and values of this dictionary are then merged with the template context, for all templates in the app::

@app.context_processor
def inject_user():
    return dict(user=g.user)

上述のcontext processorはuserと呼ばれる変数を、テンプレートの中でg.userの値を使って利用可能にします。この例は、テンプレートではどのみちgは利用可能であるためそれほど興味深いものではありませんが、どのように機能するかについてのアイデアは与えます。 The context processor above makes a variable called `user` available in the template with the value of `g.user`. This example is not very interesting because `g` is available in templates anyways, but it gives an idea how this works.

変数は値に限定されません; context processorはテンプレートで関数も利用可能にします(Pythonでは関数の受け渡しができるため): Variables are not limited to values; a context processor can also make functions available to templates (since Python allows passing around functions)::

@app.context_processor
def utility_processor():
    def format_price(amount, currency=u'€'):
        return u'{0:.2f}{1}'.format(amount, currency)
    return dict(format_price=format_price)

上述のcontext processorはformat_price関数をすべてのテンプレートで利用可能にします: The context processor above makes the `format_price` function available to all templates::

{{ format_price(0.33) }}

format_priceをテンプレートのフィルタとして構築することも可能ですが(フィルタの登録を見てください)、これはcontext processor中の関数をどう渡すかを実演しています。 You could also build `format_price` as a template filter (see :ref:`registering-filters`), but this demonstrates how to pass functions in a context processor.