2011-12-22 13 views
8

私は開発のためにBottle.pyとGoogle App Engineのdev_appserverでJinja2テンプレートを使用しています。私は、テンプレートを自動的にすべての要求に(または理想的には変更時に)リロードして、サーバーを再起動する必要はありません。bin.pyのJinja2テンプレートキャッシュを無効にする最も良い方法は何ですか?

ボトルのドキュメントによると、bottle.debug(True)を呼び出すと、テンプレートのキャッシュを無効にできるはずです。

まだJinjaはテンプレートをキャッシュしているようです。私はこれがボトルのjinja2アダプタが書かれている方法であると信じています(デフォルトのJinja2ローダーを使用し、多くの設定オプションを公開しません)。

Jinja2 Docs後、私はすべての時間をリロードテンプレートをトリガするために期待されるこのカスタムローダーを書いたが、どちらか動作していないよう:私は再起動するまで

import settings 
from bottle import jinja2_template 
from bottle import Jinja2Template, template as base_template 
class AutoreloadJinja2Template(Jinja2Template): 
    def loader(self, name): 
     def uptodate(): 
      # Always reload the template if we're in DEVMODE (a boolean flag) 
      return not settings.DEVMODE 
     fname = self.search(name, self.lookup) 
     if fname: 
      with open(fname, "rb") as f: 
       source = f.read().decode(self.encoding) 
      return (source, fname, uptodate) 


template = functools.partial(base_template, 
    template_adapter=AutoreloadJinja2Template, 
    template_lookup = settings.TEMPLATE_PATHS, 
    template_settings={ 
     'auto_reload': settings.DEVMODE 
    } 
) 

テンプレートは、まだキャッシュされ得ていますdev_appserver。これはかなり一般的な問題でなければなりません。誰にも解決策がありますか?

UPDATE:

私のような何かをやってしまった:

class CustomJinja2Template(Jinja2Template): 
    if settings.DEVMODE: 
     def prepare(self, *args, **kwargs): 
      kwargs.update({'cache_size':0}) 
      return Jinja2Template.prepare(self, *args, **kwargs) 

template = functools.partial(original_template, template_adapter=CustomJinja2Template) 

これは、テンプレートは常にリロードが行われますが、Pythonのモジュールがタッチされた場合にのみ。つまり、テンプレートファイルを編集するだけの場合は、インポートしたPythonファイルの1つを編集するまで変更内容が反映されません。あたかもテンプレートがまだどこかにキャッシュされているようです。 Jinja2の中

答えて

6

私はボトルのテンプレート溶液を完全に捨て、純粋なjinja2を使用してこの問題を解決しました。 JijnjaのFileSystemLoaderが唯一のファイル変更を見ることができるようです。

次のように私は(それだけに使用されたボトルのように、views/内のファイルを検索します)新しいtemplate機能を定義した:

@route('/hello') 
def hello(): 
    return template('index.tpl', {'text': "hello"}) 

違いから:

from jinja2 import Environment, FileSystemLoader 

if local_settings.DEBUG: 
    jinja2_env = Environment(loader=FileSystemLoader('views/'), cache_size=0) 
else: 
    jinja2_env = Environment(loader=FileSystemLoader('views/')) 

def template(name, ctx): 
    t = jinja2_env.get_template(name) 
    return t.render(**ctx) 

は、その後、私はこのようにそれを使用しますボトルのAPIは、ファイル名に.tplを含める必要があり、コンテキスト変数を辞書として渡す必要があるということです。

3

Environmentオブジェクトは、キャッシュサイズの設定値を持っていると、マニュアルに従って、

If the cache size is set to 0 templates are recompiled all the time

は、あなたがこのような何かを試してみましたか?

from jinja2 import Environment 
env = Environment(cache_size=0) 
1

ボトルビューデコレータを使用すると、@view('your_view', cache_size=0)を行うことができます。

ボトルはサーバーアダプターにreloader=Trueパラメーターを持っていますが、SimpleTemplateでのみ動作します。この動作を他のテンプレートエンジンにも拡張しようとします。すべてのあなたのビューでそれをしたい場合は

は、多分あなたはこのような何かを行うことができます。

import functools 
view = functools.partials(view, cache_size=0) 

この方法は、あなたがこれにif文の追加デバッグモードである場合にのみ、それを行うことができますコードif bottle.DEBUG

+0

cache_size = 0引数がview()デコレータまたはtemplate()関数を使用して私のために機能しなかったため、また、(reloader = True)を実行すると、 "ローカル変数 'lockfile'が割り当て前に参照されます。" – arkanciscan

+0

@arkanciscanこのバグはおそらく自分のresponseqとは関係ありませんが、大丈夫です。ご存知のように、あなたのコメントをボトルの問題として報告しました(https://github.com/defnull/bottle/issues/278)。あなたはgithubのバグについてもっと詳しく説明できますか?どのサーバーアダプターを使用していますか?ありがとう! – iurisilvio

+0

+1バグレポートのため、ありがとう:) – defnull

5

内部にボトルキャッシュテンプレート(Jinja2キャッシングとは独立しています)。 bottle.debug(True)またはbottle.run(..., debug=True)でキャッシュを無効にするか、bottle.TEMPLATES.clear()でキャッシュをクリアすることができます。

+0

お返事ありがとうございます。私はbottle.TEMPLATES.clear()について知りませんでしたが、これは便利です! 私はプロジェクトの始めからbottle.debug(True)を設定していましたので、Jinjaのキャッシュを設定することが問題だったと確信しています。 – leted

+0

ボトルを実行すると、bottle.debug(True)がbottle.runの前に実行されています。 bottle.runのデバッグ引数のデフォルト値はFalseで、指定されていなければbottle.DEBUGを上書きします。 –

関連する問題