67

PythonモジュールをJinjaテンプレートにインポートして、その関数を使用できるようにすることはできますか?

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

{% 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'

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

4

6 に答える 6

67

テンプレート内では、いいえ、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 %}
于 2011-01-28T14:04:02.513 に答える
39

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

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

テンプレートでは、他の関数と同じように呼び出します。

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

関数はPythonの第一級市民であるため、他のものと同じようにそれらを渡すことができます。必要に応じて、モジュール全体を渡すこともできます。

于 2012-08-08T02:43:00.277 に答える
15

テンプレートは知りませんが、 :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() }}
于 2018-01-15T20:27:12.180 に答える
4

モジュール__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 %}
于 2013-06-13T08:03:36.057 に答える
1

render次のように機能するようにモジュールを渡すことができます。

from src.constants import proto

wls = {"workloads": [{"name": "test1", "p": "UDP"}, {"name": "test2", "p": "TCP_NONTLS"}]}

env = Environment(
        loader=PackageLoader("src", "templates")
    )
template = env.get_template("lds.yaml.j2")
print(template.render(wls,proto=proto))

jinjaテンプレートで使用できるようになりましたproto

{% if workload.p == proto.udp -%}
于 2021-05-11T07:56:18.150 に答える
0

Flaskを使用している場合は、 Flaskコンテキストプロセッサを使用してJinjaコンテキストにインポートを追加できます。たとえば、モジュール、、をすべてのテンプレートで使用できるようにする方法は次のdatetimeとおりemail.utilsですos.path

app = Flask(__name__)

import email.utils, datetime, os.path
@app.context_processor
def add_imports():
    # Note: we only define the top-level module names!
    return dict(email=email, datetime=datetime, os=os)
于 2021-08-24T11:01:02.570 に答える