私が書いた数十のカスタムフィルターを含むjinja_filters.pyファイルがあります。現在、これらのフィルターを使用する必要がある複数のFlaskアプリがあります(問題がFlask固有であるかどうかはわかりません)。
私がやりたいことを達成するための1つのハッキーな方法は次のことです。
app = Flask(__name__)
import jinja_filters
@app.template_filter('filter_name1')
def filter_name1(arg):
return jinja_filters.filter_name1(arg)
@app.template_filter('filter_name2')
def filter_name2(arg):
return jinja_filters.filter_name2(arg)
...
これを行うための「正しい」方法は何ですか?
編集:理想的には、各フィルター名をリストする必要はありません。したがって、jinja_filters.pyに新しいフィルターを追加するときに、他のコードを更新する必要はありません。すべてのアプリですぐに使用できます。
アプリオブジェクト(おそらくapp.py)を設定する場合は常に、カスタムフィルターをインポートしてから、Jinja環境属性を変更するだけで済みます。
import jinja_filters
app = Flask(__name__)
app.jinja_env.filters['filter_name1'] = jinja_filters.filter_name1
app.jinja_env.filters['filter_name2'] = jinja_filters.filter_name2
等々。
もう1つの可能性は、inspect
モジュールを使用して、次のようにjinja_filters
内のすべてのメソッドを検索することです。
from inspect import getmembers, isfunction
import jinja_filters
app = Flask(__name__)
my_filters = {name: function
for name, function in getmembers(jinja_filters)
if isfunction(function)}
app.jinja_env.filters.update(my_filters)
そのコードはテストされていませんが、jinja_filters
ファイルに存在する関数名と関数の辞書を作成してから、Jinja環境のフィルター辞書をフィルターで更新するというアイデアがあります。
Flaskブループリント を使用してこれを行うための推奨される方法があります。そのユースケースの1つは、特にこの機能です。
- ブループリントを介して、テンプレートフィルター、静的ファイル、テンプレート、およびその他のユーティリティを提供します。ブループリントは、アプリケーションを実装したり、機能を表示したりする必要はありません。
flask.Blueprint
オブジェクトを作成し、それを使用して、flask.Flask
appオブジェクトの場合と同様に、 Blueprint.app_template_filter
デコレータまたは Blueprint.add_app_template_filter
メソッド。
# filters.py
import jinja2
import flask
blueprint = flask.Blueprint('filters', __name__)
# using the decorator
@jinja2.contextfilter
@blueprint.app_template_filter()
def filter1(context, value):
return 1
# using the method
@jinja2.contextfilter
def filter2(context, value):
return 2
blueprint.add_app_template_filter(filter2)
次に、アプリオブジェクトにブループリントを登録する必要があります。
# app.py
import flask
import filters
app = flask.Flask(__name__)
app.register_blueprint(filters.blueprint)
そして、voilà、フィルターが登録されています。