tornado学习笔记(三)

  • 3 Extending Templates

    • 1 blocks and substitutions
    • 2 autoescaping
    • 3 UI modules
      • basic module usage
      • modules in depth
      • embedding javascript and css

3 Extending Templates

1 blocks and substitutions

模板可以继承于基类模板,这样可以重复使用很多模块减少代码量

如在index.html中继承main.html,在index.html的开头加上:{% extends "main.html" %}

block:划定一些扩展模板的时候可能需要修改的代码块,在子类中直接通过block name就可以重写这一块

如在main.html中:

<header>
    {% block  header %}{% end %}
</header>

在子模板index.html中:

{% extend main.html %}

{% block header %}
    <h1>hello world</h1>
{% end %}

2 autoescaping

escape的意思就是转义,将一些原本是script中的符号换一些编码表示,如<变为&lt;, 在浏览器显示的时候才显示出原来的字符,这样是为了安全起见,比如别人在文章评论中可能上传一些<script>alert(‘dangerous...‘)</script>的文本来进行攻击,会导致我们打开网页弹出警告框.

默认情况下tornado会自动escape模板中的内容,但有些时候自动转义会导致一些变量无法正常使用,如在模板中有

{% set mailLink = "<a href=\"mailto:[email protected]\">Contact Us</a>" %}
{{ mailLink }}

本来是设置一个邮件地址作为变量,但是由于转义变成类似&lt;a href=&quot;mailto:[email protected] 为了处理这种情况,我们可以自己设置关闭自动转义,加上{% autoescape None %}

关闭自动转义虽然可以处理但是又少了保护机制,所以还有一种解决方法是加上raw block: {% raw mailLink %}

3 UI modules

Modules是继承于tornado的UIModule类的一个python类,当遇到{% module Foo(...) %}这种标签,会调用模块的render函数,返回一个string替换module标签。

UI模块可以嵌入js,css文件

basic module usage

要在模板中使用module,首先需要在应用中声明,ui_modules参数接受一个dict将模块名字映射到渲染它们的类

hello.py

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 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()

hello.html

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

例子中ui_modules={‘Hello‘: HelloModule}定义Hello模块是用HelloModule类来进行处理,所以html中间中的模块标签会被替换为HelloModule类中返回的内容

modules in depth

在看Burt‘s books的例子,现在建立一个页面用来推荐一些书,每一本书都是用同样的模板进行渲染,创建modules/book.html文件:

<div class="book">
    <h3 class="book_title">{{ book["title"] }}</h3>
    {% if book["subtitle"] != "" %}
        <h4 class="book_subtitle">{{ book["subtitle"] }}</h4>
    {% end %}
    <img src="{{ book["image"] }}" class="book_image"/>
    <div class="book_details">
        <div class="book_date_released">released: {{ book["date_released"] }}</div>
        <div class="book_date_added">added: {{ locale.format_date(book["date_added"], relative=False) }}</div>
        <h5>description:</h5>
        <div class="book_body">{% raw book["description"] %}</div>
</div>
</div>

这个模板接受名为book的字典,然后定义展示一本书的形式,函数locale.format_date()是tornado中提供时间功能的函数,参数为时间,relative=False说明是绝对时间

在recommended.html中,对每一本书调用Book模块来进行渲染:

{% extends "main.html" %}

{% block body %}
<h2>recommended reading</h2>
    {% for book in books %}
        {% module Book(book) %}
    {% end %}
{% end %}

在py文件中,建立RecommendedHandler类和BookModule类

class RecommendedHandler(tornado.web.RequestHandler):
    def get(self):
        self.render(
            "recommended.html",
            page_title="burt‘s books | recommended reading",
            header_text="recommended reading",
            books=[
                {
                    "title": "Programming Collective Intelligence",
                    "subtitle": "Building Smart Web 2.0 Applications",
                    "image": "/static/images/collective_intelligence.gif",
                    "author": "Toby Segaran",
                    "date_added": 1310248056,
                    "date_released": "August 2007",
                    "isbn": "978-0-596-52932-1",
                    "description": "<p>This fascinating book demonstrates how you " +
                                   "can build web applications to mine the enormous " +
                                   "amount of data created by people... </p>"
                },
            ]
        )

class BookModule(tornado.web.UIModule):
    def render(self, book):
        return self.render_string(‘modules/book.html‘, book=book)

if __name__ == "__main__":
    ...
    ui_modules = {
        "Book": BookModule,
    }
    ...

render_string是将模板渲染后以string的形式返回,这里的逻辑是请求首先通过RecommendedHandler类来处理,这个类使用模板recommended.html来渲染,然后在这个模板中对于每一本书的渲染将调用BookModule类来处理

embedding javascript and css

一些用来在模板中嵌入jss,cs,html等的函数:

  • embedded_css()
  • embedded_javascript()
  • html_body()
  • css_files()
  • javascript_files()

1.embedded_javascript

class BookModule(tornado.web.UIModule):
    def render(self, book):
        return ...
    def embedded_javascript(self):
        return "document.write(\"hi!\")"

2.函数中插入的内容在html中将会内置在<script>标签中,放在</body>标签的前面

<script type="text/javascript">
    document.write("hi")
</script>

3.embedded_css用法类似,插入的内容内置在<style>标签中,eg

def embedded_css(self):
    return ".book {background-color:#F5F5F5}"

4.html_body()函数可以在</body>前加入html语句

def html_body(self):
    reutrn "<script>document.write(...)</script>"

5.css_files(), javascript_files()可以引用css,js文件

def css_files(self):
    return "static/css/style.css"

def javascript(self):
    return "https://ajax.googleapis.com/ajax/.../jquery-ui.min.js"
时间: 2024-10-29 05:22:55

tornado学习笔记(三)的相关文章

Tornado学习笔记(三)

记录一些Tornado中的常用知识. 获取远端IP,直连tornado,用self.request.remote_ip,如果是走nginx反向代理方式,需要在nginx中的Server/Location配置如下                 proxy_pass http://data.xxx.com;                 #proxy_redirect off;                 proxy_set_header Host $host;               

Caliburn.Micro学习笔记(三)----事件聚合IEventAggregator和 Ihandle&lt;T&gt;

Caliburn.Micro学习笔记(三)----事件聚合IEventAggregator和 Ihandle<T> 今天 说一下Caliburn.Micro的IEventAggregator和IHandle<T>分成两篇去讲这一篇写一个简单的例子 看一它的的实现和源码 下一篇用它们做一个多语言的demo 这两个是事件的订阅和广播,很强大,但用的时候要小心发生不必要的冲突. 先看一下它的实现思想 在Caliburn.Micro里EventAggregator要以单例的形式出现这样可以

OpenCV for Python 学习笔记 三

给源图像增加边界 cv2.copyMakeBorder(src,top, bottom, left, right ,borderType,value) src:源图像 top,bottem,left,right: 分别表示四个方向上边界的长度 borderType: 边界的类型 有以下几种: BORDER_REFLICATE # 直接用边界的颜色填充, aaaaaa | abcdefg | gggg BORDER_REFLECT # 倒映,abcdefg | gfedcbamn | nmabcd

NFC学习笔记——三(在windows操作系统上安装libnfc)

本篇翻译文章: 这篇文章主要是说明如何在windows操作系统上安装.配置和使用libnfc. 一.基本信息 1.操作系统: Windows Vista Home Premium SP 2 2.硬件信息: System: Dell Inspiron 1720 Processor: Intel Core 2 Duo CPU T9300 @ 2.5GHz 2.5GHz System type: 32-bit Operating System 3.所需软件: 在windows操作系统上安装软件需要下列

swift学习笔记(三)关于拷贝和引用

在swift提供的基本数据类型中,包括Int ,Float,Double,String,Enumeration,Structure,Dictionary都属于值拷贝类型. 闭包和函数同属引用类型 捕获则为拷贝.捕获即定义这些常量和变量的原作用域已不存在,闭包仍然可以在闭包函数体内引用和修改这些值 class属于引用类型. Array的情况稍微复杂一些,下面主要对集合类型进行分析: 一.关于Dictionary:无论何时将一个字典实例赋给一个常量,或者传递给一个函数方法时,在赋值或调用发生时,都会

加壳学习笔记(三)-简单的脱壳思路&amp;调试思路

首先一些windows的常用API: GetWindowTextA:以ASCII的形式的输入框 GetWindowTextW:以Unicaode宽字符的输入框 GetDlgItemTextA:以ASCII的形式的输入框 GetDlgItemTextW:以Unicaode宽字符的输入框 这些函数在使用的时候会有些参数提前入栈,如这函数要求的参数是字符串数目.还有大小写啦之类的东西,这些东西是要在调用该函数之前入栈,也就是依次push,就是说一般前面几个push接着一个call,那前面的push可能

【Unity 3D】学习笔记三十四:游戏元素——常用编辑器组件

常用编辑器组件 unity的特色之一就是编辑器可视化,很多常用的功能都可以在编辑器中完成.常用的编辑器可分为两种:原有组件和拓展组件.原有组件是编辑器原生的一些功能,拓展组件是编辑器智商通过脚本拓展的新功能. 摄像机 摄像机是unity最为核心组件之一,游戏界面中显示的一切内容都得需要摄像机来照射才能显示.摄像机组件的参数如下: clear flags:背景显示内容,默认的是skybox.前提是必须在render settings 中设置天空盒子材质. background:背景显示颜色,如果没

马哥学习笔记三十二——计算机及操作系统原理

缓存方式: 直接映射 N路关联 缓存策略: write through:通写 write back:回写 进程类别: 交互式进程(IO密集型) 批处理进程(CPU密集型) 实时进程(Real-time) CPU: 时间片长,优先级低IO:时间片短,优先级高 Linux优先级:priority 实时优先级: 1-99,数字越小,优先级越低 静态优先级:100-139,数据越小,优先级越高 实时优先级比静态优先级高 nice值:调整静态优先级   -20,19:100,139   0:120 ps

lucene学习笔记(三)

好几天没更新了.更新一下,方便自己和大家学习. 这是最基本的代码 package index; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document;

python 学习笔记 三 字典

字典 Python的高效的key/value哈希表结构叫做"dict", dict的内容可以写成一系列的key:value对并放入{ }中, 相当于: dict = {key1:value1, key2:value2, ...}, 一个空的字典就是俩个大括号{ }. 下面是从一个空字典创建字典以及一些关键点: 数字, 字符串和元组可以作为字典的key, value可以是任何类型(包括字典). ## Can build up a dict by starting with the the