tornado學習筆記(三)

3 Extending Templates

1 blocks and substitutions

模板能夠繼承於基類模板,這樣能夠重複使用不少模塊減小代碼量javascript

如在index.html中繼承main.html,在index.html的開頭加上:{% extends "main.html" %}css

block:劃定一些擴展模板的時候可能須要修改的代碼塊,在子類中直接經過block name就能夠重寫這一塊html

如在main.html中:java

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

在子模板index.html中:python

{% extend main.html %}

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

2 autoescaping

escape的意思就是轉義,將一些本來是script中的符號換一些編碼表示,如<變爲&lt;, 在瀏覽器顯示的時候才顯示出原來的字符,這樣是爲了安全起見,好比別人在文章評論中可能上傳一些<script>alert('dangerous...')</script>的文原本進行攻擊,會致使咱們打開網頁彈出警告框.jquery

默認狀況下tornado會自動escape模板中的內容,但有些時候自動轉義會致使一些變量沒法正常使用,如在模板中有web

{% set mailLink = "<a href=\"mailto:contact@burtsbooks.com\">Contact Us</a>" %}
{{ mailLink }}

原本是設置一個郵件地址做爲變量,可是因爲轉義變成相似&lt;a href=&quot;mailto:contact@burtsbooks.... 爲了處理這種狀況,咱們能夠本身設置關閉自動轉義,加上{% autoescape None %}ajax

關閉自動轉義雖然能夠處理可是又少了保護機制,因此還有一種解決方法是加上raw block: {% raw mailLink %}api

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"
相關文章
相關標籤/搜索