转载

Tornado学习笔记(2)

表单和模板

import os.path  import tornado.httpserver import tornado.ioloop import tornado.options import tornado.web  from tornado.options import define, options define("port", default=8000, help="run on the given port", type=int)  class IndexHandler(tornado.web.RequestHandler):     def get(self):         self.render('index.html')  class PoemPageHandler(tornado.web.RequestHandler):     def post(self):         noun1 = self.get_argument('noun1')         noun2 = self.get_argument('noun2')         verb = self.get_argument('verb')         noun3 = self.get_argument('noun3')         self.render('poem.html', roads=noun1, wood=noun2, made=verb,                 difference=noun3)  if __name__ == '__main__':     tornado.options.parse_command_line()     app = tornado.web.Application(         handlers=[(r'/', IndexHandler), (r'/poem', PoemPageHandler)],         template_path=os.path.join(os.path.dirname(__file__), "templates")     )     http_server = tornado.httpserver.HTTPServer(app)     http_server.listen(options.port)     tornado.ioloop.IOLoop.instance().start()          

这个表单包括了多个文本,其中的内容在用户点击提交之后以 POST 请求的方式发送到 /poem 。Tornado为了响应这个请求会自动跳到poem.html,并且插入你在表单中填写的值。

渲染摸板

这和我在第一章里看到的例子差不多 RequestHandler 传给 tornado.web.Application 对象。但是还是有区别的,首先是传递了一个 template_path 参数。 template_path 参数告诉Tornado在哪里寻找模板文件。而这里的 self.render() 方法则是告诉Tornado来读取模板文件,并将结果返回给浏览器。

然而这里的 index.html 并不完整,它的确是一个已经写好的HTML标记,但是一般情况下我们会输出我们所希望HTML结合程序传入给模板的值。 {{}} 所括起来的字符串,括起来的字符串就是占位符,我们在渲染模板的时候会希望以实际的值代替。这里还是可以通过 render() 函数传递所希望表达出来的关键字参数。例如这里的:

self.render('poem.html', roads=noun1, wood=noun2, made=verb, difference=noun3)

这里就告诉模板我们将传入的参数。

这里的 {{}} 可以填充任意的Python表达式:

>>> from tornado.template import Template >>> print Template("{{2+3}}").generate() 5 >>> print Template({{'gogogojuststudy'[-5:]}}").generate() study >>>

同样可以在Tornado模板中使用条件和循环语句。控制语句以 {% %} 包围。

一般以 {%if condition%} 。依旧可以使用for,while等条件控制语句,但是要记得以 {%end %} 结尾。

这里有其他的一些默认提供的一些便利的函数:

escape() #替换字符串中的&、为他们对应的HTML字符
url_escape() #使用urlib。quote_plus替换字符串s中的字符为URL编码形式。
squeeze() #过滤字符串,把连续的多个空白字符替换成一个空格

模板扩展

Tornado可以方便我们扩展一个已经存在的模板,只需要在新的模板文件顶部放上 {%extends “filename.html”%} 这里便是使得新的HTML文件继承了父HTML文件的所有标签。

这里我们就需要用到块了, block 语句可以帮助我们改变一些模板元素。每个 {%block %} 对应一个 {% end%}

UI模块

UI模块是封装模板中包含的标记、样式以及行为的可复用组件。它所定义的元素通常用于多个模板交叉复 用或在同一个模板中重复使用。模块本身是一个继承自Tornado的 UIModule 类的简单Python类,并定义 了一个 render() 方法。

import tornado.web import tornado.httpserver import tornado.ioloop import tornado.options import os.path  from tornado.options import define, options define("port", default=8000, help="run on the given port", type=int)  class HelloHandler(tornado.web.RequestHandler):     def get(self):         self.render('hello.html')  class HelloModule(tornado.web.UIModule):     def render(self):         return '<h1>Hello, world!</h1>'  if __name__ == '__main__':     tornado.options.parse_command_line()     app = tornado.web.Application(         handlers=[(r'/', HelloHandler)],         template_path=os.path.join(os.path.dirname(__file__), 'templates'),         ui_modules={'Hello': HelloModule}     )     server = tornado.httpserver.HTTPServer(app)     server.listen(options.port)     tornado.ioloop.IOLoop.instance().start()

这个例子里 ui_module 字典里只有一项,这里把名为Hello模块的引用和定义的 HELLOMODULE 结合起来。当我们调用 HelloHandler 并渲染 hello.html 时,可以使用{% module Hello()%}模板标签来包含 HelloModulerender() 方法返回的字符串。

例如在这里:

<html>     <head> <title>UI Module Example</title> </head>     <body>  {% module Hello() %}     </body>  </html>

这里通过模板标签自身的位置调用 HelloModule 返回的字符串进行填充。

嵌入JavaScript和CSS

为了给这些模块提供更高的灵活性,Tornado允许你使用embedded_css和embedded_javascript方法嵌 入其他的CSS和JavaScript文件

不仅仅是可以返回一个JavaScript和CSS规则,而且更加灵活的是在闭合的标签前添加完整的HTML标记。

你可以使用javascript_files()和css_files()来 包含完整的文件,不论是本地的还是外部的。

def css_files(self):     return "/static/css/newreleases.css" 
def javascript_files(self):     return"https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js" 
正文到此结束
Loading...