2011-12-22 75 views
8

我正在使用Jinja2模板與Bottle.py和Google App Engine的dev_appserver進行開發。我希望模板能夠在每次請求時自動重新加載(或者理想情況下只在它們改變時),這樣我纔不必重新啓動服務器。在bottle.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文件後,所做的更改纔會生效。看起來好像模板仍然被緩存在某處。

回答

6

我解決了這個問題,徹底拋棄瓶子的模板解決方案,並使用純jinja2。似乎Jijnja的FileSystemLoader是唯一一個可以觀察文件更改的人。

我定義的新template功能如下(它會在views/文件,就像使用瓶裝):

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) 

然後我用這樣的:

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

從差瓶子的API是你必須在文件名中包含.tpl,並且你必須傳遞上下文變量作爲字典。

3

Environment對象在Jinja2的具有高速緩存大小配置值,並根據該文件,

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)

Bottle在服務器適配器中有一個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 2012-01-31 21:23:52

+0

@arkanciscan這個bug可能與我的responseq沒有關係,但是沒關係。只是你知道,我報告你的評論是一個問題瓶(https://github.com/defnull/bottle/issues/278)。你可以提供關於github中bug的更多細節嗎?你使用哪個服務器適配器?謝謝! – iurisilvio 2012-02-02 00:10:59

+0

錯誤報告+1,謝謝:) – defnull 2012-02-02 12:48:56

5

在內部瓶緩存模板(獨立於Jinja2緩存)。您可以通過bottle.debug(True)bottle.run(..., debug=True)來禁用高速緩存,或使用bottle.TEMPLATES.clear()清除高速緩存。

+0

感謝您的回覆。我不知道bottle.TEMPLATES.clear(),它可以派上用場! 我從項目開始就設置了bottle.debug(True),所以我很確定這是配置Jinja緩存的一個問題。 – leted 2012-02-05 02:25:21

+0

絆倒我的是在bottle.run之前運行bottle.debug(True)。 bottle.run的調試參數具有默認值False,如果未指定,它將覆蓋bottle.DEBUG。 – 2013-01-02 22:16:56

相關問題