前言

  • 之前的文章有個栗子,檢視函式可以直接返回一段 html 程式碼,瀏覽器可以自動渲染
  • 但是當你的 HTML 非常複雜的話,也要整串寫在程式碼裡面嗎,這顯然不合理的,可閱讀性也非常差
  • 所以,就誕生了 Jinja2 這種模板引擎來解決需要返回複雜 jinja2 模板程式碼的問題

簡單的栗子

以下是一個 jinja2 的模板,它對登入和未登入使用者顯示不同的資訊

<html>
{% if login %}
<p>你好,{{name}}</p>
{% else %}
<a href='/login'>登入</a>
{% endif %}
</html>

如果使用者已經登入:變數 login 為真、變數 name 為 tom,模板被渲染成如下的 html 檔案

<html>
<p>你好,tom</p>
</html>

如果使用者沒有登入:變數 login 為假,模板被渲染成如下的 html 檔案:

<html>
<a href='/login'>登入</a>
</html>

Flask 中使用模板

目錄結構

一般來說 templates 就是存放模板的目錄

jinja2 模板程式碼

<!DOCTYPE html>
<html>
<body>
<h2>My name is {{ name }}, I am {{ age }} years old</h2>
</body>
</html>

flask 程式碼

  • 首先,需要 import render_template
  • 然後,檢視函式呼叫 render_template,對模板 templates/index.html 進行渲染
  • render_template 包含有 2 個命名引數:name 和 age,模板引擎將模板 templates/index.html 中的變數進行替換
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
return render_template('index.html', name='tom', age=10) app.run(debug=True)

瀏覽器的執行效果

分界符

jinja2 模板檔案混合 html 語法與 jinja2 語法,使用分界符區分 html 語法與 jinja2 語法。有 5 種常見的分界符:

  • {{ 變數 }},將變數放置在 {{ 和 }} 之間;
  • {% 語句 %},將語句放置在 {% 和 %} 之間;
  • {# 註釋 #},將註釋放置在 {# 和 #} 之間;
  • ## 註釋,將註釋放置在 # 之後

變數

語法

jinja2 模板中,使用  {{ var }}  包圍的識別符號稱為變數,模板渲染會將其替換為 Python 中的變數,語法如下:

 {{ 變數 }}

jinja2 模板

<html>
{{ string }} <ul>
<li> {{ list[0] }}
<li> {{ list[1] }}
<li> {{ list[2] }}
<li> {{ list[3] }}
</ul> <ul>
<li> {{ dict['name'] }}
<li> {{ dict['age'] }}
</ul>
</html>

包含有 3 種類型的變數:字串、列表、字典,它們會被替換為同名的 Python 變數

flask 程式碼

from flask import Flask, render_template

app = Flask(__name__)

string = 'www.imooc.com'
list = ['www', 123, (1, 2, 3), {"name": "poloyy"}]
dict = {'name': 'zhangsan', 'age': True} @app.route('/2')
def index2():
return render_template('index2.html', string=string, list=list, dict=dict) app.run(debug=True)

列表的值包含字串、數字、元組、字典,字典的值包含字串、布林值

瀏覽器的執行效果

for 語句

語法

jinja2 模板中,使用  {% 語句 %}  包圍的語法塊稱為語句,jinja2 支援類似於 Python 的 for 迴圈語句,語法如下:

{% for item in iterable %}
{% endfor %}

有些教程會說有另一種等價寫法

# for item in iterable
# endfor 

但我實驗發現並不生效

jinja2 模板程式碼

<h1>Members</h1>
<ul>
{% for user in users %}
<li>{{ user }}</li>
{% endfor %} # for item in iterable
<li>{{ user }}</li>
# endfor
</ul>

Flask 程式碼

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠蘿測試筆記
# blog: https://www.cnblogs.com/poloyy/
# time: 2021/7/11 6:04 下午
# file: 6_jinja2.py
"""
from flask import Flask, render_template app = Flask(__name__) users = ['tom', 'jerry', 'mike'] @app.route('/3')
def index3():
return render_template('index3.html', users=users, iterable=users) app.run(debug=True)

瀏覽器的執行效果

能看到 # for 的寫法並沒有生效

if 語句

語法

jinja2 模板中,使用  {% 語句 %}  包圍的語法塊稱為語句,jinja2 支援類似於 Python 的 if-else 判斷語句,語法如下:

{% if cond %}
{% elif cond %}
{% else %}
{% endif %} 

jinja2 模板程式碼

<html>
{% if a %}
<p>a is True</p>
{% else %}
<p>a is False</p>
{% endif %} {% if b %}
<p>b is True</p>
{% elif c %}
<p>b is False, and c is True</p>
{% endif %}
</html>

Flask 程式碼

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠蘿測試筆記
# blog: https://www.cnblogs.com/poloyy/
# time: 2021/7/11 6:04 下午
# file: 6_jinja2.py
"""
from flask import Flask, render_template app = Flask(__name__) @app.route('/4')
def index4():
a = False
b = False
c = True
return render_template('index4.html', a=a, b=b, c=c) app.run(debug=True) 

瀏覽器的執行效果

tests

語法

jinja2 提供的 tests 可以用來在語句裡對變數或表示式進行測試,語法如下:

{% variable is test %}

完整的 test 請參考 https://jinja.palletsprojects.com/en/latest/templates/#builtin-tests,部分的 test 如下:

test 名稱 功能
defined 變數是否已經定義
boolean 變數的型別是否是 boolean
integer 變數的型別是否是 integer
float 變數的型別是否是 float
string 變數是否是 string
mapping 變數的型別是否是字典
sequence 變數的型別是否是序列
even 變數是否是偶數
odd 變數是否是奇數
lower 變數是否是小寫
upper

變數是否是大寫

jinja2 模板程式碼

<html>
{% if number is odd %}
<p> {{ number }} is odd
{% else %}
<p> {{ number }} is even
{% endif %} {% if string is lower %}
<p> {{ string }} is lower
{% else %}
<p> {{ string }} is upper
{% endif %}
</html>

jinja2 的模板輸入

number = 404
string = 'HELLO'

渲染後的 html

<html>
<p> 404 is even
<p> HELLO is upper
</html>

過濾器

語法

jinja2 過濾器的是一個函式,語法如下:

{{ variable | filter }}
  • 執行函式呼叫 filter(varialbe),把函式返回值作為這個程式碼塊的值
  • 暫時不舉具體的栗子了,只做簡單介紹,目測後面我會出詳細文章講解 jinja2

jinja2 模板

<html>
{{ string | upper }}
</html>

jinja2 的模板輸入

string = 'hello'

渲染後的 html

<html>
HELLO
</html>