Cherrypy下的Cheetah:如何加载基础模板,并在开发过程中自动监测变更

2 投票
2 回答
2314 浏览
提问于 2025-04-15 21:04

我正在开发一个使用cherrypy和cheetah的应用,想要提升开发的体验。

在我手动提前编译模板的时候,一切都能正常工作。(更新:这是生产环境下的工作方式:预编译,不要发送*.tmpl文件,并将模板作为普通的Python模块加载。)不过在开发阶段,我更希望每次引用模板时都能直接加载,这样就不需要每次都杀掉并重启我的应用。我遇到了一些问题:

  1. 如果我的模板是从基础模板继承的,我会遇到导入错误(找不到基础模板)。我记得在实验的时候这个是可以工作的,但很不幸的是我没有保存,现在又搞不定了。
  2. 假设我解决了第一个问题,怎么才能让即使是基础模板的修改也能被及时识别,而不需要重启。

下面是我的示例应用,应该能展示出这些问题。目录结构如下:

t.py
templates/
    base.tmpl
    index.tmpl

t.py:

import sys

import cherrypy
from Cheetah.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

这样运行它:

python t.py Something

2 个回答

1

试试这个:

base.tmpl 替换成:

#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
1

看起来这个问题在另一个StackOverflow的问题中已经有点答案了。通过使用 cheetah_import 这个函数,我可以像这样写我的方法:

@cherrypy.expose
def index(self):
    templates = cheetah_import('templates.index')
    t = getattr(getattr(templates, 'index'), 'index')(searchList=[{'foo': self.foo}])
    return t.respond()

我还需要在模板目录里添加一个 __init__.py 文件。这个方法还要求Cherrypy的 engine.autoreload_on 设置要设为 True

为了让生产环境更高效,我可以把 cheetah_import = __import__ 这样写,而不是替换掉默认的 __builtin__.import

撰写回答