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"})
注意:最好在所有的路由下面使用,否則可能導致其他路由不可用
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 %}