Tornado框架06-模板

01-靜態文件

static_path引用文件

配置靜態文件的路徑,告訴tornado從文件系統中的一個特定的位置提取靜態文件
使用:

"static_path": os.path.join(BASE_DIRS, "static")

作用:
引入其他文件

<!--<link rel="stylesheet" href="/static/css/home.css" />-->
<link rel="stylesheet" href="{{static_url('css/home.css')}}" />

請求:

http://127.0.0.1:9808/static/html/index.html

StaticFileHandler

使用原因

http://127.0.0.1:9808/static/html/index.html這種請求方式不友好

本質

tornado預置的用來提供靜態資源文件的handler

作用:自由映射靜態文件

使用

(r'/(.*)$', tornado.web.StaticFileHandler,{"path":os.path.join(config.BASE_DIRS, "static/html")})
(r'/(.*)$', tornado.web.StaticFileHandler, {"path": os.path.join(config.BASE_DIRS, "static/html"),"default_filename":"index.html"})

注意:最好在所有的路由下面使用,否則可能導致其他路由不可用

1.http://127.0.0.1/static/html/index.html

2.http://127.0.0.1/

3.http://127.0.0.1/view/index.html

02-模板

路徑與渲染

使用模板,需要仿照靜態文件路徑設置一樣,向web.Application類的構造函數傳遞一個名爲template_path的參數來告訴Tornado從文件系統的一個特定位置提供模板文件,如:

app = tornado.web.Application(
    [(r'/', IndexHandler)],
    static_path=os.path.join(os.path.dirname(__file__), "statics"),
    template_path=os.path.join(os.path.dirname(__file__), "templates"),
)

在這裏,我們設置了一個當前應用目錄下名爲templates的子目錄作爲template_path的參數。在handler中使用的模板將在此目錄中尋找。
現在我們將靜態文件目錄statics/html中的index.html複製一份到templates目錄中,此時文件目錄結構爲:

├── statics
│   ├── css
│   │   ├── index.css
│   │   ├── main.css
│   │   └── reset.css
│   ├── html
│   │   └── index.html
│   ├── images
│   │   ├── home01.jpg
│   │   ├── home02.jpg
│   │   ├── home03.jpg
│   │   └── landlord01.jpg
│   ├── js
│   │   ├── index.js
│   │   └── jquery.min.js
│   └── plugins
│       ├── bootstrap
│       │   └─...
│       └── font-awesome
│           └─...
├── templates
│   └── index.html
└── test.py

在handler中使用render()方法來渲染模板並返回給客戶端。

class IndexHandler(RequestHandler):
    def get(self):
        self.render("index.html") # 渲染主頁模板,並返回給客戶端。

模板語法

變量與表達式

在tornado的模板中使用{{}}作爲變量或表達式的佔位符,使用render渲染後佔位符{{}}會被替換爲相應的結果值。
我們將index.html中的一條房源信息記錄

class HomeHandler(RequestHandler):
    def get(self, *args, **kwargs):
        temp = 18
        self.render('home.html', age=temp)


class HomeHandler(RequestHandler):
    def get(self, *args, **kwargs):
        temp = 18
        per = {
            "name":"sun",
            "height":175
        }
        stu = {
            "id":123456,
            "weight":50
        }
        self.render('home.html', age=temp, per=per, **stu)      

改爲模板:

<h1>年齡:{{age}}</h1> 
<h1>年齡:{{age + 10}}</h1>

<h1>{{per["name"]}}</h1>
<h1>{{per["height"]}}</h1>

<h1>{{id}}</h1>
<h1>{{weight}}</h1>

{{}}不僅可以包含變量,還可以是表達式,如:

控制語句

可以在Tornado模板中使用Python條件和循環語句。控制語句以{\%和\%}包圍,並以類似下面的形式被使用:

{% if page is None %}
或
{% if len(entries) == 3 %}

控制語句的大部分就像對應的Python語句一樣工作,支持if、for、while,注意end:

{% if ... %} ... {% elif ... %} ... {% else ... %} ... {% end %}
{% for ... in ... %} ... {% end %}
{% while ... %} ... {% end %}

函數

static_url()
Tornado模板模塊提供了一個叫作static_url的函數來生成靜態文件目錄下文件的URL。讀取配置中的static_path值,並將參數拼接到該路徑下返回一個新路徑如下面的示例代碼:

<link rel="stylesheet" href="{{ static_url("style.css") }}">

這個對static_url的調用生成了URL的值,並渲染輸出類似下面的代碼:

<link rel="stylesheet" href="/static/style.css?v=ab12">

優點:
- static_url函數創建了一個基於文件內容的hash值,並將其添加到URL末尾(查詢字符串的參數v)。這個hash值確保瀏覽器總是加載一個文件的最新版而不是之前的緩存版本。無論是在你應用的開發階段,還是在部署到生產環境使用時,都非常有用,因爲你的用戶不必再爲了看到你的靜態內容而清除瀏覽器緩存了。
- 另一個好處是你可以改變你應用URL的結構,而不需要改變模板中的代碼。例如,可以通過設置static_url_prefix來更改Tornado的默認靜態路徑前綴/static。如果使用static_url而不是硬編碼的話,代碼不需要改變。

轉義

寫入的js程序並沒有運行,而是顯示出來了:
我們查看頁面源代碼,發現<、>、”等被轉換爲對應的html字符
這是因爲tornado中默認開啓了模板自動轉義功能,防止網站受到惡意攻擊。

class Transferred(RequestHandler):
    def get(self, *args, **kwargs):
        str = "<h1>sun is a good man</h1>"
        # str = "<script>alert('sunck good')</script>"
        self.render('transferred.html', str=str)

模板:將str當成一個普通字符串來顯現

<body>
    {{str}}
</body>

我們可以通過raw語句來輸出不被轉義的原始格式,如:

關閉當前標籤中的自動轉義
{% raw text %}

注意:在Firefox瀏覽器中會直接彈出alert窗口,而在Chrome瀏覽器中,需要set_header(“X-XSS-Protection”, 0)
若要關閉自動轉義,一種方法是在Application構造函數中傳遞

autoescape=None,

另一種方法是在每頁模板中修改自動轉義行爲,添加如下語句:

關閉當前頁面的自動轉義
{% autoescape None %}

escape()
已經關閉了自動轉義,但是在某個位置需要開啓自動轉義,如:

{{ escape(text) }}

自定義函數

在模板中還可以使用一個自己編寫的函數,只需要將函數名作爲模板的參數傳遞即可,就像其他變量一樣。
我們修改後端如下:
index.py

def mySum(a, b):
    return a + b
self.render('home.html', age=temp, per=per, flag=False, stus=stus, mySum=mySum, **stu)

模板

<h1>使用自定義函數:{{mySum(5,8)}}</h1>

我們可以使用塊來複用模板,塊語法如下:
父模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{title}}</title>
</head>
<body>
    {% block main %}

    {% end %}
</body>
</html>

而子模板index.html使用extends來使用父模板base.html,如下:

{% extends "base.html" %}

{% block main %}
<h1>sunck is a handsome man</h1>
{% end %}
發佈了48 篇原創文章 · 獲贊 4 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章