Flaskで a を使用してかなり奇妙な問題が発生していますjinja2.ChoiceLoader
(また、複数のパスを使用して試しましたがFileSystemLoader
、喜びはありません)。
そのように、いくつかの「テーマ」ディレクトリがあります。
/templates/
themes/
default/
layout.html
menu.html
blue/
layout.html
grey/
menu.html
...
default/
そして、選択したテーマに必要なテンプレートがない場合にフォールバックしたいので、ChoiceLoader を使用しました。
@app.before_request
def setup_request():
current_theme = get_theme()
logging.info('Using theme %s'%(current_theme))
app.jinja_loader = jinja2.ChoiceLoader([
jinja2.FileSystemLoader('/templates/themes/%s/'%(current_theme)),
jinja2.FileSystemLoader('/templates/themes/default/')
])
それは素晴らしいことですが、変更し<current_theme>
ても、Apache をリロードするか、Flask 開発サーバーを再起動するまで、古いフォルダーからテーマが読み込まれます。
新しいテーマを使用する必要があります。ロギングは、変更されたテーマを使用していると言っていますが、明らかにapp.jinja_loader
ハニーアナグマに少し似ています...Apacheをリロードするまで完全に無視しています。
編集:これは、同じ名前のすべてのファイルが同じファイルであると考えるFlaskに関連しているようです。組み込みサーバー (DEBUG=True)、Cherry、mod_wsgi で再現できます。この人も同様の問題を抱えているようですが、単純な解決策はありません:フラスコ ブループリント テンプレート フォルダー1 つのアプリにテンプレートをカスケードする必要があるという意味で、私の状況は異なります。彼の問題はブループリント間のテンプレートのカスケードに関連していますが、内部では同じ問題である可能性があります。
「get_theme()」呼び出しのコードは次のとおりです。
def get_theme():
# I know this is unsafe, testing only
return request.args.get('theme','default')
編集 2: CSS だけでなく、テーマ間で HTML と JavaScript を変更する必要があります。これが、さまざまな CSS ファイルをロードするだけではない理由です。また、これらのテーマの一部はモバイル デバイス用であり、他のテーマとの共通点はほとんどありません。
編集 3: 2 つのソリューション。解決策 1 : 「blue.layout.html」や「default.layout.html」のように、ファイルに一意の名前を付けます。これは完全に機能しますが、必要に応じてカスケードしません。解決策 2 : 相対パスを使用するため、代わりにinclude 'file.html'
を使用しますinclude 'theme/blue/file.html
。get_theme_file()
アクティブなテーマをチェックし、ファイルが存在するかどうかをチェックし (存在しない場合は「デフォルト」テーマにフォールバック)、相対パスを返す関数を作成することで、カスケードを実現しました。含めるすべてが のように見えることを確認する必要があります{% include get_theme_file('file.html') %}
。これはエレガントではありませんが、ここで使用された Flask を使用した低レベルの操作よりもエレガントであることがわかりました。