私はjinja2を使用していますが、マクロを呼び出す場合と同様の構文を使用して、ヘルパーとしてpython関数を呼び出したいと思います。 jinja2は、関数呼び出しができないようにすることを意図しているようで、マクロとして関数をテンプレートにコピーすることで繰り返します。
これを行う簡単な方法はありますか?そして、python関数のセット全体をインポートし、多くのリガマロールを行わずに(拡張機能の作成など)、それらをjinja2からアクセスできるようにする方法はありますか?
Flaskを使用している場合は、これを__init__.py
に入れてください:
def clever_function():
return u'HELLO'
app.jinja_env.globals.update(clever_function=clever_function)
そしてあなたのテンプレートで{{ clever_function() }}
でそれを呼び出します
注:これはFlask固有です!
この投稿はかなり古いものですが、コンテキストプロセッサを使用してFlaskの新しいバージョンでこれを行うより良い方法があります。
変数は簡単に作成できます:
@app.context_processor
def example():
return dict(myexample='This is an example')
上記は、次のようにFlaskを含むJinja2テンプレートで使用できます。
{{ myexample }}
(This is an example
を出力します)
および本格的な機能:
@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)
上記のように使用した場合:
{{ format_price(0.33) }}
(通貨記号で入力価格を出力します)
別の方法として、 jinja filters を使用して、Flaskにベイクできます。例えば。デコレータの使用:
@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
上記の2つの方法で適用されたフィルターは、次のように使用できます。
{% for x in mylist | reverse %}
{% endfor %}
from jinja2 import Template
def custom_function(a):
return a.replace('o', 'ay')
template = Template('Hey, my name is {{ custom_function(first_name) }} {{ func2(last_name) }}')
template.globals['custom_function'] = custom_function
Matroskin's answer に従ってフィールドに関数を与えることもできます
fields = {'first_name': 'Jo', 'last_name': 'Ko', 'func2': custom_function}
print template.render(**fields)
出力されます:
Hey, my name is Jay Kay
Jinja2バージョン2.7.3で動作
また、デコレータでtemplate.globals
の関数の定義を簡単にしたい場合は、チェックアウト Bruno Bronosky's answer
@ AJP's answer が好きです。たくさんの機能ができるまで、そのまま使いました。それから Python関数デコレータ に切り替えました。
from jinja2 import Template
template = '''
Hi, my name is {{ custom_function1(first_name) }}
My name is {{ custom_function2(first_name) }}
My name is {{ custom_function3(first_name) }}
'''
jinga_html_template = Template(template)
def template_function(func):
jinga_html_template.globals[func.__name__] = func
return func
@template_function
def custom_function1(a):
return a.replace('o', 'ay')
@template_function
def custom_function2(a):
return a.replace('o', 'ill')
@template_function
def custom_function3(a):
return 'Slim Shady'
fields = {'first_name': 'Jo'}
print(jinga_html_template.render(**fields))
良い機能には__name__
があります!
公式ドキュメントやスタックオーバーフローでこのような簡単な方法を見たことはありませんが、これを見つけたときは驚きました:
# jinja2.__version__ == 2.8
from jinja2 import Template
def calcName(n, i):
return ' '.join([n] * i)
template = Template("Hello {{ calcName('Gandalf', 2) }}")
template.render(calcName=calcName)
# or
template.render({'calcName': calcName})
ラムダを使用して、テンプレートをメインコードに接続します
return render_template("clever_template", clever_function=lambda x: clever_function x)
その後、テンプレート内の関数をシームレスに呼び出すことができます
{{clever_function(value)}}
Jinja2からpython関数を呼び出すには、グローバルと同様に機能するカスタムフィルターを使用できます。 http://jinja.pocoo.org/docs/dev/api/#writing-filters
とてもシンプルで便利です。 myTemplate.txtファイルに次のように書きました。
{{ data|pythonFct }}
pythonスクリプト内:
import jinja2
def pythonFct(data):
return "This is my data: {0}".format(data)
input="my custom filter works!"
loader = jinja2.FileSystemLoader(path or './')
env = jinja2.Environment(loader=loader)
env.filters['pythonFct'] = pythonFct
result = env.get_template("myTemplate.txt").render(data=input)
print(result)
python関数のセット全体をインポートし、jinja2からアクセスできるようにする方法はありますか?
はい、あります、上記の他の答えに加えて、これは私のために働きます。
クラスを作成し、それに関連するメソッドを設定します。
class Test_jinja_object:
def __init__(self):
self.myvar = 'sample_var'
def clever_function (self):
return 'hello'
次に、ビュー関数でクラスのインスタンスを作成し、結果のオブジェクトをrender_template関数のパラメーターとしてテンプレートに渡します
my_obj = Test_jinja_object()
テンプレートで、次のようにjinjaのクラスメソッドを呼び出すことができます
{{ my_obj.clever_function () }}
すべての組み込み関数をインポートするには、次を使用できます。
app.jinja_env.globals.update(__builtins__)
これが機能しない場合は、.__dict__
の後に__builtins__
を追加します。
John32323の回答 に基づきます。
Djangoで実行している場合は、コンテキストで関数を渡すことができます。
context = {
'title':'My title',
'str': str,
}
...
return render(request, 'index.html', context)
これで、jinja2テンプレートでstr
関数を使用できるようになります。