回答:
Flaskを使用している場合は、これを次の場所に配置します__init__.py
。
def clever_function():
return u'HELLO'
app.jinja_env.globals.update(clever_function=clever_function)
テンプレートでそれを呼び出します {{ clever_function() }}
from jinja2 import Template ##newline## def clever_function(): ##newline## return "Hello" ##newline## template = Template("{{ clever_function() }}") ##newline## print(template.render(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) }}
(通貨記号付きの入力価格を出力します)
または、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 %}
__init__.py
あなたがflask.Flask(__name__)
そこで宣言したと仮定します。
jinjaは意図的に「任意」のpythonをテンプレート内で実行することを難しくしていると思います。テンプレートのロジックを少なくすることは良いことであるという意見を強制しようとします。
Environment
インスタンス内のグローバル名前空間を操作して、関数への参照を追加できます。テンプレートをロードする前に実行する必要があります。例えば:
from jinja2 import Environment, FileSystemLoader
def clever_function(a, b):
return u''.join([b, a])
env = Environment(loader=FileSystemLoader('/path/to/templates'))
env.globals['clever_function'] = clever_function
import utils.helpers env.globals['helpers'] = utils.helpers
{{ clever_function('a', 'b') }}
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の答えに従ってフィールドで関数を与えることもできます
fields = {'first_name': 'Jo', 'last_name': 'Ko', 'func2': custom_function}
print template.render(**fields)
出力されます:
Hey, my name is Jay Kay
Jinja2バージョン2.7.3で動作します
そして、デコレータで関数の定義を簡単にしたい場合は、Bruno Bronoskyの答えをtemplate.globals
チェックしてください
@AJPの回答が好きです。たくさんの機能ができるようになるまで、そのまま使用しました。次に、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の回答に基づく。
はるかに簡単な決定があります。
@app.route('/x')
def x():
return render_template('test.html', foo=y)
def y(text):
return text
次に、test.htmlで:
{{ y('hi') }}