I’m using Jinja2 templates with Bottle.py and Google App Engine’s dev_appserver for development. I want the templates to automatically reload on every request (or ideally only when they change), so that I don’t have to keep restarting the server.
According to bottle’s docs, you’re supposed to be able to disable template caching by calling bottle.debug(True).
Jinja still seems to be caching its templates, though. I believe this to be because of the way the bottle jinja2 adapter is written (it just uses a default Jinja2 loader and doesn’t expose many configuration options).
Following the Jinja2 Docs, I wrote this custom Loader that I would expect to trigger a template reload every time, but it doesn’t seem to work either:
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
}
)
Templates are still getting cached until I restart dev_appserver. This must be a fairly common problem. Does anyone have a solution that works?
UPDATE:
I ended up doing something like:
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)
This causes the templates to always reload, but only if a python module has been touched. i.e. if you just edit a template file, the changes won’t take affect until you edit one of the python files that imports it. It seems as if the templates are still being cached somewhere.
I resolved this issue by ditching bottle’s template solutions completely and using pure jinja2. It seems that Jijnja’s
FileSystemLoaderis the only one, which can watch for file changes.I defined new
templatefunction as follows (it looks for files inviews/, just like bottle used to):Then I use it like this:
The difference from bottle’s API is that you have to include
.tplin file name and you have to pass context variables as dictionary.