Forms and Templates
ex poem maker pro
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)
新建两个类,注意最后返回的页面是使用render()来进行渲染的,模板分别是index.html和poem.html,render函数还可以带关键字参数
现在在工程目录下建立目录templates用来放置html模板文件,同时在Application类里增加新目录的路径:
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()
template_path指明查找模板文件的路径
下面是html文件,tornado的模板与django的类似
index.html
<!DOCTYPE html> <html> <head><title>Poem Maker Pro</title></head> <body> <h1>Enter terms below.</h1> <form method="post" action="/poem"> <p>Plural noun<br><input type="text" name="noun1"></p> <p>Singular noun<br><input type="text" name="noun2"></p> <p>Verb (past tense)<br><input type="text" name="verb"></p> <p>Noun<br><input type="text" name="noun3"></p> <input type="submit"> </form> </body> </html>
poem.html
<!DOCTYPE html> <html> <head><title>Poem Maker Pro</title></head> <body> <h1>Your poem</h1> <p>Two {{roads}} diverged in a {{wood}}, and I—<br> I took the one less travelled by,<br> And that has {{made}} all the {{difference}}.</p> </body> </html>
template syntax
模板中的{{ var }}
表示变量,运行时会被替换为这个变量的真实的值,这里是通过self.render('poem.html', roads=noun1, wood=noun2,...)传递到模板的 {{ }}
中还可以是python的表达式,执行时会对表达式先求值再进行替换
>>> from tornado.template import Template >>> print Template("{{1+1}}").generate() 2 >>> print Template("{{', '.join([str(x*x) for x in range(10)]) }}").generate() 0, 1, 4, ... , 81
control flow statements
条件控制语句放在{% %}
中
eg,
<html> <head> ... </head> <body> <h1>{{header}}</h1> <ul> {% for book in books %} <li>{{ book }}</li> {% end %} </ul> </body> </html>
using functions in templates
- escape(s) : 将字符串s中的&,<,>替换为相应的html对象
- url_escape(s)
- json_encode(val)
- squeeze(s): 将超过一个的连续空格符替换为一个
将函数传递到模板中:只要将函数名字作为参数放在generate()函数中,eg,
>>> from tornado.template import Template >>> def disemvowel(s): ... return ''.join([x for x in s if x not in 'aeiou']) ... >>> disemvowel("george") 'grg' >>> print Template("my name is {{d('mortimer')}}").generate(d=disemvowel) my name is mrtmr
static files
类似模板的方法,先建立目录static,然后在Application中添加路径
app = tornado.web.Application( handlers=[(r'/', IndexHandler), (r'/poem', MungedPageHandler)], template_path=os.path.join(os.path.dirname(__file__), "templates"), static_path=os.path.join(os.path.dirname(__file__), "static"), debug=True )
这里设置debug=True后,只要修改服务器代码,会自动重启服务器来使用这些修改
static文件夹可以放置css,js,jpg等静态文件,这些文件可以用static_url来得到访问的url,如在index.html中,
<link rel="stylesheet" href="{{ static_url("style.css") }}">
运行时static_url会得到一个真实的url值,链接将会类似与这种形式:
<link rel=... href="/static/style.css?v=ab12">
使用static_url来得到url而不是直接写上真实url,目的是减少硬编码