Flask(8)- jinja2 模板入門

前言

  • 之前的文章有個栗子,視圖函數可以直接返回一段 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:  //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:  //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 請參考 //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>