web-dev-qa-db-ja.com

PythonモジュールをJinjaテンプレートにインポートしますか?

PythonモジュールをJinjaテンプレートにインポートして、その機能を使用できますか?

たとえば、日付と時刻をフォーマットするメソッドを含むformat.pyファイルがあります。 Jinjaマクロでは、次のようなlikeを行うことができますか?

{% from 'dates/format.py' import timesince %}

{% macro time(mytime) %}
<a title="{{ mytime }}">{{ timesince(mytime) }}</a>
{% endmacro %}

format.pyはテンプレートではないため、上記のコードでは次のエラーが表示されます。

UndefinedError: the template 'dates/format.py' (imported on line 2 in 'dates/macros.html') does not export the requested name 'timesince'

...しかし、これを達成する別の方法があるかどうか疑問に思っていました。

43
Matt Norris

テンプレート内では、いいえ、pythonコードをインポートできません。

これを行う方法は、次のように、関数をjinja2 カスタムフィルター として登録することです。

pythonファイル:

from dates.format import timesince

environment = jinja2.Environment(whatever)
environment.filters['timesince'] = timesince
# render template here

テンプレートで:

{% macro time(mytime) %}
<a title="{{ mytime }}">{{ mytime|timesince }}</a>
{% endmacro %}
54
Wooble

関数をテンプレートに渡すだけです

from dates.format import timesince
your_template.render(timesince)

テンプレートで、他の関数と同じように呼び出すだけで、

{% macro time(mytime) %}
    <a title="{{ mytime }}">{{ timesince(mytime) }}</a>
{% endmacro %}

関数はpythonのファーストクラスの市民なので、他の関数と同じように渡すことができます。必要に応じて、モジュール全体を渡すこともできます。

24
nightpool

テンプレートは import を知りませんが、 importlib で教えることができます:

import importlib
my_template.render( imp0rt = importlib.import_module )  # can't use 'import', because it's reserved

(名前を付けることもできます"import"引数にdictを渡すことにより)

kwargs = { 'import' : importlib.import_module }
my_template.render( **kwargs )

次に、jinja-templateで、任意のモジュールをインポートできます。

{% set time = imp0rt( 'time' ) %}
{{ time.time() }}
7
Skandix

モジュールで使用可能なすべてのシンボルをエクスポートするには、モジュール__dict__をパラメーターとしてjinjaテンプレートrenderメソッドに提供します。以下は、__ builtin__の使用可能な関数と型、検査および型モジュールをテンプレートに提供します。

import __builtin__
import inspect
import types

env=RelEnvironment()
template = env.get_template(templatefile)

export_dict={}
export_dict.update(__builtin__.__dict__)
export_dict.update(types.__dict__)
export_dict.update(inspect.__dict__)

result=template.render(**export_dict)

テンプレート内で、エクスポートされたモジュールの機能を次のように使用します。

{%- for element in getmembers(object) -%}
{# Use the getmembers function from inspect module on an object #}
{% endfor %}
2
Simon Black