Cheetah with Cherrypy: how to load base templates, and do so automatically on change during development
I am working on a cherrypy+cheetah app and would like to improve the development experience.
I have everything working when I manually compile templates beforehand. (Update: This is how things work for production: precompile, don't ship *.tmpl and load templates as regular python modules.) However, during development I'd rather just load the templates every time they are referenced so that I don't need to kill and restart my application. I have a couple of issues I am facing:
- If I have templates inheriting from base templates, I get import errors (can't find base templates). I think I had this actually working during my experiments, but unfortunately didn't save it and now I can't make it work.
- Suppose I get 1. working, how do make it so that edits even in base templates get picked up without restart.
Below is my sample application that should demonstrate the problems. The directory structure is as follows:
t.py
templates/
base.tmpl
index.tmpl
t.py:
import sys
import cherrypy
from Chee开发者_Go百科tah.Template import Template
class T:
def __init__(self, foo):
self.foo = foo
@cherrypy.expose
def index(self):
return Template(file='templates/index.tmpl',
searchList=[{'foo': self.foo}]).respond()
cherrypy.quickstart(T(sys.argv[1]))
base.tmpl:
#def body
This is the body from the base
#end def
This is the base doc
index.tmpl:
#from templates.base import base
#extends base
#def body
$base.body(self)
This is the extended body
#end def
This is from index
Run it like this:
python t.py Something
Try this:
Replace base.tmpl
with:
#from Cheetah.Template import Template
#def body
#set $base = Template(file="templates/base.tmpl")
$base.body()
<br/>
This is the extended body
#end def
$body()
<br/>
This is from index
Looks like this question was kind of answered in another SO question. By using the cheetah_import function, I can write my methods like this:
@cherrypy.expose
def index(self):
templates = cheetah_import('templates.index')
t = getattr(getattr(templates, 'index'), 'index')(searchList=[{'foo': self.foo}])
return t.respond()
I will also need to add an __init__.py
into the templates directory. This approach also requires that Cherrypy's engine.autoreload_on
setting is set to True
.
To make production more efficient, I can make cheetah_import = __import__
and not replace the default __builtin__.import
.
精彩评论