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_cssembedded_javascriptjavascipt_filescss_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 是在页面的 <head> 部分,而 JavaScript 被渲染在页面结尾 </body> 之前的位 置。

在不需要额外 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 ... %} 不同,模块式模板使用了和它们的上级模板不同的命名 空间——它们只能访问到全局模板命名空间和它们自己的关键字参数。

powered by Gitbook 该教程制作时间: 2016-04-18 10:09:01