Flaskのrender_templateのラッパーを作ってデフォルトで値を渡せるようにする

はじめに

Flaskのページ表示の部分で、設定値など、毎回必ずテンプレートに渡したい値がありまして、都度書きたくなかったのでデフォルトで渡すラッパーを作りました。

アプローチ

  • 独自のrender_templateメソッドを作成し、基本的にそのメソッドを使う
  • render_templateの内部では、Flaskのrender_templateを呼び出す。引数として与えられた値に、デフォルトで入れたいものを追加してrender_templateを呼び出す。

ディレクトリ構成

.
├── app.py
├── app_conf.py
├── templates
│   └── index.html
└── wrappers
    └── render_template.py

コード

app.py

呼び出し部分です。

本来ならflaskのrender_templateを使うところを、カスタムのwrapperのrender_templateを使うことで、app_confの値を毎回テンプレートに渡すことができます。

from flask import Flask
from wrappers.render_template import render_template # 独自のラッパー

app = Flask(__name__)

@app.route('/')
def index():
    title = 'Title'
    return render_template('index.html', title=title)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

app_conf.py

設定をdictで記述します。このファイルをwrapperクラスから読み込んで使います。

app_config = {
    'product_name': 'Sample Product',
    'feature_1_enabled': True,
    'feature_2_enabled': True
}

templates/index.html

テンプレートです。

<h1>{{title}} | {{app_config.product_name}}</h1>
{% if app_config.feature_1_enabled %}
    <li>feature 1 is on</li>
{% endif %}
{% if app_config.feature_2_enabled %}
    <li>feature 2 is on</li>
{% endif %}

wrappers/render_templates.py

ラッパー本体です。キーワード引数にapp_configの値を加えてそのままflaskのrender_templateに渡しています。

from flask import render_template as flask_render_template
import app_conf

デフォルトで渡したい設定

app_config = app_conf.app_config

def render_template(*args, **kwargs):
    if kwargs.get('app_config') is None:
        kwargs['app_config'] = app_config
    return flask_render_template(*args, **kwargs)      

終わりに

簡単なwrapperクラスを書くことで、フィーチャーフラグなどの設定を一括で管理してテンプレートに渡せるようになりました。
また、import文だけを書き換えることで、既存の呼び出しコードの変更はしないで済むのも嬉しい点でした。