Jinja2是Python下一個被普遍應用的模版引擎,他的設計思想來源於Django的模板引擎,並擴展了其語法和一系列強大的功能。其中最顯著的一個是增長了沙箱執行功能和可選的自動轉義功能,這對大多應用的安全性來講是很是重要的。html
基於unicode並能在python2.4以後的版本運行,包括python3。python
要想使用Jinja2模板,須要從flask導入render_template函數,而後在路由函數中調用render_template函數,該函數第一個參數就是模板名字。模板默認保存在目錄。flask
最簡單的模板文件就是普通的HTML文件,但靜態文件沒什麼意義,須要在訪問路由時傳入響應的參數,並在模板中以必定的樣式顯示在瀏覽器中,所以,須要用到render_template函數的關鍵字參數。假設有一個模板文件hello.html,代碼以下:瀏覽器
<h1> hello,{{name}}.</h1>
這個用{{......}}括起來的部分就是模板表達式。在使用render_template函數調用模板文件hello.html時,須要經過關鍵字參數指定name值。安全
render_template('hello.html',name='star')
返回給客戶端時,{{name}}會被替換成star.
網頁輸出代碼服務器
<h1> hello,star.</h1>
1. 變量顯示語法: {{ 變量名 }} 2. for循環: {% for i in li%} {% endfor %} 3. if語句 {% if user == 'westos'%} {% elif user == 'hello' %} {% else %} {% endif%}
# templates目錄裏面創建mubna.html文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hello</title> </head> <body> <p>變量:{{ name }}</p> <p>列表:{{ li }}</p> <p>列表元素: {% for item in li %} <br/>{{ item }} {% endfor %}</p> <p>字典:{{ d }}</p> <p>字典元素: {{ d.a }} {{ d['b'] }}</p> <p>對象:{{ u }}</p> <table> <tr> <td>用戶</td> <td>密碼</td> </tr> <tr> <td>{{ u.name }}</td> <td>{{ u.passwd }}</td> </tr> </table> </body> </html>
from flask import Flask, render_template app = Flask(__name__) class User(object): def __init__(self, name, passwd): self.name = name self.passwd = passwd def __str__(self): return "<User: %s>" %(self.name) @app.route('/') def index1(): name = "sheen is cute !!" li = [1, 2, 4, 5] d = dict(a=1, b=2) u = User("westos", "passwd") return render_template('muban.html', name = name, li = li, d = d, u = u ) app.run()
服務端給客戶端返回的數據可能來自於多種數據源。這些數據格式可能並不能知足客戶端需求,就須要對數據進行再加工。
過濾器須要放在模板表達式變量的後面,與變量之間用'|'分割,{{ vlaue|upper}}將value英文字母都轉換爲大寫形式。app
編寫一個時間過濾器,將時間戳轉換爲特定格式的字符串時間
from flask import Flask, render_template import time app = Flask(__name__) def time_format(value,format="%Y-%m-%d %H:%M:%S"): # 時間戳----> 元組 t_time = time.localtime(value) # 元組 ----> 指定字符串 return time.strftime(format,t_time) # 第一個參數是過濾器函數,第二個參數是過濾器名稱 app.add_template_filter(time_format,'time_format') @app.route('/chtime/') def chtime(): return render_template('chtime.html',timestamp = time.time()) app.run()
# templates/目錄下的chtime.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> 時間戳 {{ timestamp }} <br/> 格式化後的時間 {{ timestamp | time_format }} </body> </html>
在編寫python程序時,會有不少地方調用一樣或相似的代碼。這種狀況,能夠把重複使用的代碼放到函數或類中,只須要訪問函數或類的實例就能夠實現代碼複用。Jinja2 模板中使用宏來防止代碼冗餘。函數
Jinja2 模板中的宏須要放到{%......%},使用修飾,支持參數,而且使用{% endmacro %}結束 若是宏要被多個模板文件共享,就須要將宏單獨放到一個模板文件中,而後使用{% import ….%}指令導入該模板
## templates/目錄下的macro.html {% macro input(type, name, text ) %} <div class="form-group"> <label>{{ text }}</label> <input name={{ name }} type={{ type }} class="form-control"> </div> {% endmacro %}
# # templates/目錄下的login.html {% extends "base.html" %} {% block title %} 登錄 {% endblock %} {% block content %} <div class="container container-small"> <h1>登陸 <small>沒有帳號?<a href="signup.html">註冊</a></small> </h1> {# /*將表單信息提交給/login路由對應的函數進行處理, 而且提交信息的方式爲post方法, 爲了密碼的安全性*/#} <form action="/login/" method="post"> <!--<div class="form-group">--> <!--<label>用戶名/手機/郵箱</label>--> <!--<input name="user" type="text" class="form-control">--> <!--</div>--> {% import 'macro.html' as macro %} {#調用宏模板#} {{macro.input('text', 'user', "用戶名/手機/郵箱" )}} {{macro.input('password','passwd', "密碼" )}} <!--<div class="form-group">--> <!--<label>密碼</label>--> <!--<input name="passwd" type="password" class="form-control">--> <!--</div>--> <div class="form-group"> <button class="btn btn-primary btn-block" type="submit">登陸</button> </div> <div class="form-group"> <a href="#">忘記密碼?</a> </div> <!--獲取服務器傳遞給後臺的變量message, jinja2模板引擎裏面的語法--> {% if message %} <p style="color: red">{{ message }}</p> {% endif %} </form> </div> {% endblock %}
#主程序 from flask import Flask, render_template app = Flask(__name__) @app.route('/login/') def login(): return render_template('login.html') app.run()
Jinja2模板還有另外一種代碼複用技術,就是模板繼承。當一個模板被另外的模板繼承時,能夠經過{{ super() }} 訪問父模板的資源。在一個模板中繼承另外一個模板,須要extends 指令。如 child.txt 模板文件從 parent.txt 繼承的代碼post
{% extends ‘parents.txt’ %}
child.txt 從parent.txt模板繼承後,會自動使用parent.txt 中的全部代碼,但要放在spa
{% block xxxx%} .... {% endblock %}
中的代碼須要child.txt中使用{{super() }}引用。其中,xxxx是塊(block)的名字
模板繼承語法:
1. 如何繼承某個模板? {% extends "模板名稱" %} 2. 如何挖坑和填坑? 挖坑: {% block 名稱 %} 默認值 {% endblock %} 填坑: {% block 名稱 %} {% endblock %} 3. 如何調用/繼承被替代的模板? 挖坑: {% block 名稱 %} 默認值 {% endblock %} 填坑: {% block 名稱 %} #如何繼承挖坑時的默認值? {{ super() }} # 後面寫新加的方法. ........ {% endblock %}
#templates目錄下創建parent.html模板文件 <!DOCTYPE html> <html lang="en"> <head> {% block head %} <meta charset="UTF-8"> <title>{% block title %}hello{% endblock %}</title> {% endblock %} </head> <body> I LOVE PYTHON! <br/> {% block body %} Cute,{{ text }} {% endblock %} </body> </html>
#templates目錄下創建child.html模板文件 {% extends 'parent.html' %} {% block title %} {#繼承挖坑時的默認值:{{ super() }}#} {{ super() }}-{{ text }} {% endblock %} {% block body %} <h1>{{ super() }},Beauty!</h1> {% endblock %}
# 主程序 from flask import Flask,render_template app = Flask(__name__) @app.route('/') def index(): return render_template('child.html',text = 'sheen') if __name__ == '__main__': app.run()