我正在使用带有Bottle.py和Google App Engine的dev_appserver的Jinja2模板进行开发。我希望模板能够在每个请求上自动重新加载(或者理想情况下只在它们发生更改时),这样我就不必继续重新启动服务器了。
根据瓶子的文档,您应该可以通过调用bottle.debug(True)
来禁用模板缓存。
在Jinja2 Docs之后,我编写了这个自定义Loader,我希望每次都能触发模板重新加载,但它似乎也不起作用:
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之前,模板仍然会被缓存。这一定是一个相当普遍的问题。有没有人有一个有效的解决方案?
更新:
我最终做了类似的事情:
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文件之前,更改不会生效。似乎模板仍在某处缓存。
答案 0 :(得分: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
,并且必须将上下文变量作为字典传递。
答案 1 :(得分:5)
瓶子内部缓存模板(独立于Jinja2缓存)。您可以通过bottle.debug(True)
或bottle.run(..., debug=True)
停用缓存,或使用bottle.TEMPLATES.clear()
清除缓存。
答案 2 :(得分:3)
jinja2中的Environment对象具有缓存大小的配置值,并且根据文档,
如果缓存大小设置为0,则会一直重新编译模板
你尝试过这样的事吗?
from jinja2 import Environment
env = Environment(cache_size=0)
答案 3 :(得分:1)
使用瓶子视图装饰器,你可以@view('your_view', cache_size=0)
。
Bottle在服务器适配器中有一个reloader=True
参数,但我想它只适用于SimpleTemplate。我将尝试将此行为扩展到其他模板引擎。
如果您想在所有观看中进行,也许您可以这样做:
import functools
view = functools.partials(view, cache_size=0)
这样,只有在调试模式下为此代码if bottle.DEBUG
添加if语句时,才能执行此操作。