在通常的 Web 程序裏,訪問一個地址一般會返回一個包含各種信息的 HTML 頁面。由於咱們的程序是動態的,頁面中的某些信息須要根據不一樣的狀況來進行調整,好比對登陸和未登陸用戶顯示不一樣的信息,因此頁面須要在用戶訪問時根據程序邏輯動態生成。html
咱們把包含變量和運算邏輯的 HTML 或其餘格式的文本叫作模板,執行這些變量替換和邏輯計算工做的過程被稱爲渲染,這個工做由咱們這一章要學習使用的模板渲染引擎——Jinja2 來完成。git
按照默認的設置,Flask 會從程序實例所在模塊同級目錄的 templates 文件夾中尋找模板,咱們的程序目前存儲在項目根目錄的 app.py 文件裏,因此咱們要在項目根目錄建立這個文件夾:github
$ mkdir templates複製代碼
在社交網站上,每一個人都有一個主頁,藉助 Jinja2 就能夠寫出一個通用的模板:flask
<h1>{{ username }}的我的主頁</h1>
{% if bio %}
<p>{{ bio }}</p> {# 這裏的縮進只是爲了可讀性,不是必須的 #}
{% else %}
<p>自我介紹爲空。</p>
{% endif %} {# 大部分 Jinja 語句都須要聲明關閉 #}複製代碼
Jinja2 的語法和 Python 大體相同,你在後面會陸續接觸到一些常見的用法。在模板裏,你須要添加特定的定界符將 Jinja2 語句和變量標記出來,下面是三種經常使用的定界符:數據結構
{{ ... }}
用來標記變量。{% ... %}
用來標記語句,好比 if 語句,for 語句等。{# ... #}
用來寫註釋。模板中使用的變量須要在渲染的時候傳遞進去,具體咱們後面會了解。app
咱們先在 templates 目錄下建立一個 index.html 文件,做爲主頁模板。主頁須要顯示電影條目列表和我的信息,代碼以下所示:函數
templates/index.html:主頁模板學習
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ name }}'s Watchlist</title>
</head>
<body>
<h2>{{ name }}'s Watchlist</h2>
{# 使用 length 過濾器獲取 movies 變量的長度 #}
<p>{{ movies|length }} Titles</p>
<ul>
{% for movie in movies %} {# 迭代 movies 變量 #}
<li>{{ movie.title }} - {{ movie.year }}</li> {# 等同於 movie['title'] #}
{% endfor %} {# 使用 endfor 標籤結束 for 語句 #}
</ul>
<footer>
<small>© 2018 <a href="http://helloflask.com/tutorial">HelloFlask</a></small>
</footer>
</body>
</html>複製代碼
爲了方便對變量進行處理,Jinja2 提供了一些過濾器,語法形式以下:測試
{{ 變量|過濾器 }}複製代碼
左側是變量,右側是過濾器名。好比,上面的模板裏使用 length
過濾器來獲取 movies
的長度,相似 Python 裏的 len()
函數。網站
提示 訪問 http://jinja.pocoo.org/docs/2.10/templates/#list-of-builtin-filters 查看全部可用的過濾器。
爲了模擬頁面渲染,咱們須要先建立一些虛擬數據,用來填充頁面內容:
app.py:定義虛擬數據
name = 'Grey Li'
movies = [
{'title': 'My Neighbor Totoro', 'year': '1988'},
{'title': 'Dead Poets Society', 'year': '1989'},
{'title': 'A Perfect World', 'year': '1993'},
{'title': 'Leon', 'year': '1994'},
{'title': 'Mahjong', 'year': '1996'},
{'title': 'Swallowtail Butterfly', 'year': '1996'},
{'title': 'King of Comedy', 'year': '1999'},
{'title': 'Devils on the Doorstep', 'year': '1999'},
{'title': 'WALL-E', 'year': '2008'},
{'title': 'The Pork of Music', 'year': '2012'},
]複製代碼
使用 render_template()
函數能夠把模板渲染出來,必須傳入的參數爲模板文件名(相對於 templates 根目錄的文件路徑),這裏即 'index.html'
。爲了讓模板正確渲染,咱們還要把模板內部使用的變量經過關鍵字參數傳入這個函數,以下所示:
app.py:返回渲染好的模板做爲響應
from flask import Flask, render_template
# ...
@app.route('/')
def index():
return render_template('index.html', name=name, movies=movies)複製代碼
爲了更好的表示這個視圖函數的做用,咱們把原來的函數名 hello
改成 index
,意思是「索引」,即主頁。
在傳入 render_template()
函數的關鍵字參數中,左邊的 movies
是模板中使用的變量名稱,右邊的 movies
則是該變量指向的實際對象。這裏傳入模板的 name
是字符串,movies
是列表,但可以在模板裏使用的不僅這兩種 Python 數據結構,你也能夠傳入元組、字典、函數等。
render_template()
函數在調用時會識別並執行 index.html 裏全部的 Jinja2 語句,返回渲染好的模板內容。在返回的頁面中,變量會被替換爲實際的值(包括定界符),語句(及定界符)則會在執行後被移除(註釋也會一併移除)。
如今訪問 http://localhost:5000/ 看到的程序主頁以下圖所示:
這一章咱們編寫了一個簡單的主頁。結束前,讓咱們提交代碼:
$ git add .
$ git commit -m "Add index page"
$ git push複製代碼
提示 你能夠在 GitHub 上查看本書示例程序的對應 commit:17b579d