多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
### UI 模块 Tornado 支持一些 UI 模块,它们可以帮你创建标准的,易被重用的应用程序级的 UI 组件。 这些 UI 模块就跟特殊的函数调用一样,可以用来渲染页面组件,而这些组件可以有自己的 CSS 和 JavaScript。 例如你正在写一个博客的应用,你希望在首页和单篇文章的页面都显示文章列表,你可以创建 一个叫做 `Entry` 的 UI 模块,让他在两个地方分别显示出来。首选需要为你的 UI 模块 创建一个 Python 模组文件,就叫 `uimodules.py` 好了: ``` class Entry(tornado.web.UIModule): def render(self, entry, show_comments=False): return self.render_string( "module-entry.html", entry=entry, show_comments=show_comments) ``` 然后通过 `ui_modules` 配置项告诉 Tornado 在应用当中使用 `uimodules.py`: ``` class HomeHandler(tornado.web.RequestHandler): def get(self): entries = self.db.query("SELECT * FROM entries ORDER BY date DESC") self.render("home.html", entries=entries) class EntryHandler(tornado.web.RequestHandler): def get(self, entry_id): entry = self.db.get("SELECT * FROM entries WHERE id = %s", entry_id) if not entry: raise tornado.web.HTTPError(404) self.render("entry.html", entry=entry) settings = { "ui_modules": uimodules, } application = tornado.web.Application([ (r"/", HomeHandler), (r"/entry/([0-9]+)", EntryHandler), ], **settings) ``` 在 `home.html` 中,你不需要写繁复的 HTML 代码,只要引用 `Entry` 就可以了: ``` {% for entry in entries %} {% module Entry(entry) %} {% end %} ``` 在 `entry.html` 里面,你需要使用 `show_comments` 参数来引用 `Entry` 模块,用来 显示展开的 `Entry` 内容: ``` {% module Entry(entry, show_comments=True) %} ``` 你可以为 UI 模型配置自己的 CSS 和 JavaScript ,只要复写 `embedded_css`、 `embedded_javascript`、`javascipt_files`、`css_files` 就可以了: ``` class Entry(tornado.web.UIModule): def embedded_css(self): return ".entry { margin-bottom: 1em; }" def render(self, entry, show_comments=False): return self.render_string( "module-entry.html", show_comments=show_comments) ``` 即使一页中有多个相同的 UI 组件,UI 组件的 CSS 和 JavaScript 部分只会被渲染一次。 CSS 是在页面的 `&lt;head&gt;` 部分,而 JavaScript 被渲染在页面结尾 `&lt;/body&gt;` 之前的位 置。 在不需要额外 Python 代码的情况下,模板文件也可以当做 UI 模块直接使用。 例如前面的例子可以以下面的方式实现,只要把这几行放到 `module-entry.html` 中就可以了: ``` {{ set_resources(embedded_css=".entry { margin-bottom: 1em; }") }} <!-- more template html... --> ``` 这个修改过的模块式模板可以通过下面的方法调用: ``` {% module Template("module-entry.html", show_comments=True) %} ``` `set_resources` 函数只能在 `{% module Template(...) %}` 调用的模板中访问到。 和 `{% include ... %}` 不同,模块式模板使用了和它们的上级模板不同的命名 空间——它们只能访问到全局模板命名空间和它们自己的关键字参数。