因爲tornado自帶本身的模板,要把jinja2引入tornado須要作一些特殊處理 css
在這裏,新建jinja.py 參考https://github.com/mxyzm/snail/blob/master/joiners/jinja.py html
#coding=utf-8 """Make Jinja2 work with Tornado.""" from tornado import escape from jinja2 import Environment, FileSystemLoader class JinjaApplicationMixin(object): def __init__(self, *args, **settings): super(JinjaApplicationMixin, self).__init__(*args, **settings) if "template_path" not in settings: return if "template_loader" in settings: loader = settings['template_loader'] else: loader = FileSystemLoader(settings['template_path']) if "debug" in settings: auto_reload = settings["debug"] else: auto_reload = False autoescape = bool(settings.get('autoescape', False)) self.jinja_env = Environment( loader=loader, auto_reload=auto_reload, autoescape=autoescape, ) class JinjaHandlerMixin(object): def render_string(self, template_name, **context): self.require_setting("template_path", "render") default_context = { 'handler': self, 'request': self.request, 'current_user': self.current_user, 'static_url': self.static_url, 'xsrf_form_html': self.xsrf_form_html, 'reverse_url': self.reverse_url, 'me': self.oUser, } escape_context = { 'escape': escape.xhtml_escape, 'xhtml_escape': escape.xhtml_escape, 'url_escape': escape.url_escape, 'json_encode': escape.json_encode, 'squeeze': escape.squeeze, 'linkify': escape.linkify, } context.update(default_context) context.update(escape_context) context.update(self.ui) # Enabled tornado UI modules and methods. template = self.application.jinja_env.get_template( template_name) return template.render(**context)
這裏我加了個當前用戶對象me 給前臺使用 python
而後主Application使用Mixin 繼承 JinjaApplicationMixin git
class MainApplication(JinjaApplicationMixin, tornado.web.Application): passserver.py 裏面就能夠這樣跑
application = MainApplication(make_handlers(URL_PREFIX, (r'/', include('handlers.index')), (r'/', include('handlers.user')), (r'/', include('handlers.userGroup')),BaseHandler 同Mixin JinjaHandlerMixin
class BaseHandler(JinjaHandlerMixin, tornado.web.RequestHandler): def get_current_user(self): user = self.get_secure_cookie("user") if user is not None: self.oUser = self.session.query(User).filter_by(name=user).first() return user def initialize(self): self.session = db_session self.oUser = None def on_finish(self): self.session.close()這裏已經爲Sqlalchemy的session處理和 tornado的用戶登陸驗證打好基礎,等之後再作說明。
而後在handler裏面使用: github
@route('', name='index') class IndexHandler(BaseHandler): @tornado.web.authenticated @tornado.web.asynchronous def get(self): self.render("index.html")注意:
下面是登陸窗口的示例 web
{% extends "base.html" %} {% block title %}登錄{% endblock %} {% block css %} <style type="text/css"> body { padding-top: 40px; padding-bottom: 40px; background-color: #eee; } .form-signin { max-width: 330px; padding: 15px; margin: 0 auto; } .form-signin .form-signin-heading, .form-signin .checkbox { margin-bottom: 10px; } .form-signin .checkbox { font-weight: normal; } .form-signin .form-control { position: relative; font-size: 16px; height: auto; padding: 10px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .form-signin .form-control:focus { z-index: 2; } .form-signin input[type="text"] { margin-bottom: -1px; border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .form-signin input[type="password"] { margin-bottom: 10px; border-top-left-radius: 0; border-top-right-radius: 0; } </style> {% endblock %} {% block body %} <div class="container"> <form class="form-signin" method="post"> {{ xsrf_form_html() }} <h2 class="form-signin-heading">登陸</h2> <input name="name" type="text" class="form-control" placeholder="用戶名" autofocus> <input name="pwd" type="password" class="form-control" placeholder="密碼"> {% if form|d(none) is not none %} <div class="alert alert-danger"> {{ form.mainerr}} </div> {% endif%} <label class="checkbox"> <input name="remember" type="checkbox" value="remember">記住我 </label> <button class="btn btn-lg btn-primary btn-block" type="submit">登陸</button> </form> </div> <!-- /container --> {% endblock %}靜態文件一般以下使用:
<link href="{{ static_url("css/bootstrap.min.css") }}" rel="stylesheet" media="screen">須要在 server.py裏面配置下 static_path