Python:每个应用的Mako模板查找

0 投票
1 回答
1070 浏览
提问于 2025-04-17 14:27

我正在使用cherrypy和Mako作为模板引擎。

我希望Mako根据请求的应用程序查找不同的目录。

也就是说,我有三个“应用”:网站、管理员和安装。

它们都有自己的模板文件夹,结构大致如下:

  • /template
  • /template/site
  • /template/admin
  • /template/install
  • /template/system

/system文件夹里包含一些系统范围的模板,比如404页面等。

我在尝试理解cherrypy和mako时,参考了Twiseless,但我在这方面遇到了困难。

接下来我会简单介绍一下我尝试过的方法,但要提醒一下:我觉得我可能完全走错了方向!:) 所以,如果你有任何想法或建议,可能不妨先别继续往下读了。

在我的主文件server.py中,我做了如下操作:

from libs.plugins.template import MakoTemplatePlugin

engine = cherrypy.engine
makoTemplate = MakoTemplatePlugin(engine, self.base_dir)
setTemplateDirs(makoTemplate, self.template_path)

MakoTemplatePlugin是一个稍微修改过的插件,名字和Twiseless中的同名插件相同。

这段代码的作用是设置模板查找路径,使用我全局配置文件中的默认模板目录,也就是:

  • /template
  • /template/system

然后,每次加载一个应用时,我会调用一个函数(setTemplateDirs)来更新Mako查找的目录。

我以为这样可以解决问题,但实际上并没有。起初我犯了个错误,为每个应用创建了一个新的MakoTemplatePlugin实例。结果是它们全部在每次页面加载时被调用,首先调用的是第一个实例,它只包含基本的、非应用特定的目录。

由于这个实例是第一个被调用的,它开始在错误的文件夹中查找,导致出现404错误。

于是我确保将MakoTemplatePlugin的引用传递给我的所有应用。我以为如果每次调用应用时运行setTemplateDirs,就能解决问题……但事实并非如此。

我不知道该把这个函数放在哪里才能在每次请求页面时运行……

例如:

# /apps/site/app.py

import somemodule.setTemplateDirs

class Site(object, params):
    def __init__(self):
        self.params = params
        self.makoTemplate = params['makoTemplate']
        self.base_path = params['base_path']
        setTemplateDirs(self.makoTemplate, self.base_path, '', '/')

    @cherrypy.expose
    @cherrypy.tools.render(template='index.html')
    def index(self):
        pass

这显然只在应用首次加载时有效……我尝试将更新函数调用移到一个单独的方法update中,并尝试在每个页面调用它,例如:

@cherrypy.exposed
@cherrypy.tools.render(template='index.html')
@update
def index(self):
    pass

但这只给我带来了与配置相关的错误。

与其继续在这上面纠结,肯定有更简单的方法。

你会怎么做呢?

非常感谢,

汤姆

1 个回答

0

我把这个搞定了。感谢stephan提供了mako工具示例的链接:http://tools.cherrypy.org/wiki/Mako

我只是稍微修改了一下,让它能正常工作。

如果有人好奇,这个的基本原理是你在全局配置中定义了tools.mako.directories,然后你可以在各个应用的配置文件中覆盖这个设置。

比如说:

server.conf

...
tools.mako.directories: ['', 'system']
...

site.conf

...
tools.mako.directories: ['site', 'system']
...

我还做了一些额外的工作,把相对的URI转换成绝对路径,但关键的部分上面已经解释过了。

撰写回答