0%

基礎3:Flask Jinja2 模板引擎

基礎:Flask Jinja2 模板引擎

本範例程式的目錄結構 (使用python3.x)

1
2
3
4
5
6
7
8
.
├── hello.py
└── templates
├── base.html
├── test2.html
├── test.html
└── user.html

在Jinja2 變數的表示

  • hello.py
    1
    2
    3
    4
    5
    from flask import Flask, render_template
    app = Flask(__name__)
    @app.route('/user/<name>')
    def user(name):
    return render_template('user.html', name=name)
  • user.html
    1
    <h1>Hello, {{ name }}!</h1>

    在Jinja2 變數過濾器

  • [Jinja2 官方的過濾清單]
  • 呈上一的變數的表示, hello.py不變;只更改 templates/user.html
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <h1>第一個字元大寫,其餘小寫: {{ name|capitalize }}!</h1>
    <h1>第一個字元大寫: {{ name|title }}!</h1>
    <h1>全部字元小寫: {{ name|lower }}!</h1>
    <h1>全部字元大寫: {{ name|upper }}!</h1>
    <h1>變數name2 未定義,顯示預定字串: {{ name2|default('the name2 is not defined') }}!</h1>
    <h1>變數為空值時,顯示預定字串: {{ ''|default('the string was empty',true) }}!</h1>
    <h1>刪除前後空白字元: {{ ' Hello~~~ '|trim }}!</h1>

    <h1>未移除HTML標籤: {{ '<ul><li>Hello ha</li></ul>' }}!</h1>
    <h1>轉譯前移除HTML標籤: {{ '<ul><li>Hello ha</li></ul>'|striptags }}!</h1>
    <h1>轉譯前移除HTML標籤,並再轉大寫字元: {{ '<ul><li>Hello ha</li></ul>'|striptags|upper }}!</h1>

    在Jinja2 控制結構

  • 只更改 templates/user.html,並刪除之前的內容。判斷name 變數的值是否為andy,正確返回 hello andy ; 反之,返回 Hello EveryBody
    1
    2
    3
    4
    5
    {% if name=="andy" %}
    <h1> Hello {{ name }} !!!</h1>
    {% else %}
    <h1> Hello EveryBody !!!</h1>
    {% endif %}
  • 迴圈控制。修改hello.pytemplates/test.html, 在hello.py 製造一個串列,將它帶往模板的迴圈來處理。

hello.py

1
2
3
4
@app.route('/array/')
def arrayt():
commit=[ 'test'+str(xx) for xx in range(1,10)]
return render_template('test.html',commit=commit)

templates/test.html

1
2
3
4
5
<ul>
{% for item in commit %}
<li>Hello, {{ item }}!</li>
{% endfor %}
</ul>
  • Jinja2 模板引擎也有函數結構,稱為 macro。增加以下內容到 templates/test.html
    1
    2
    3
    4
    5
    6
    7
    8
    9
    {% macro tempf(item) %}
    <li>from macro : {{ item }}!!!</li!>
    {% endmacro %}

    <ul>
    {% for item in commit %}
    {{ tempf(item) }}
    {% endfor %}
    </ul>
  • 呈上一個macro 範例,使用像是 python import用法,將macro 函數寫在 template/test2.html, 修改template/test.html在匯入 test2.html。

增加以下 到 template/test2.html

1
2
3
{% macro tempf(item) %}
<li>from macro with import : {{ item }}!!!</li!>
{% endmacro %}

修改 template/test.html

1
2
3
4
5
6
7
{% import "test2.html" as testmacro %}

<ul>
{% for item in commit %}
{{ testmacro.tempf(item) }}
{% endfor %}
</ul>

Jinja2 模板繼承

網頁是由html head ,body 等標籤兩兩成對構成,通常程式回應結果只在body 區塊有所變更,沒有必要重新將相同內容放置同一個模板中,因此可以使用模板繼承方式將基礎的模板匯進來。

  • 基礎模板: template/base.html ; 在 template/user.html繼承基礎模板。基礎模板劃分 , head 區塊(),head 裡面 title 區塊, 及 body 區塊,現在只要改變body區塊

增加以下內容 至 template/base.html

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE HTML>
<html>
<head>
{% block head %}
<title> {% block title %}who 123{% endblock %} </title>
{% endblock %}
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>

修正內容 template/user.html,使用extends 繼承 base.html

1
2
3
4
{% extends "base.html" %}
{% block body %}
<h1>Hello, {{ name }}!</h1>
{% endblock %}
  • 若要在head區塊增加 一個 meta 標籤,及改變一個tile 區塊內容

修正內容 template/user.html

1
2
3
4
5
6
7
8
{% extends "base.html" %}
{% block title %}Title Change {{ name }}{% endblock %}
{% block head %}
<meta charset="utf-8" />
{% endblock %}
{% block body %}
<h1>Hello, {{ name }}!</h1>
{% endblock %}

瀏覽結果發現,網頁title 標題不見。這是因為 title 區塊位於 head 區塊內,也就是說title 是head區塊的內容;當增加meta 標籤就會覆蓋掉原本的title 的內容。要解決此問題,只要 head 區塊在增加一個 super();表示再次引用 base.html 基礎模板中的 head 區塊內容。

1
2
3
4
5
6
7
8
9
{% extends "base.html" %}
{% block title %}Title Change {{ name }}{% endblock %}
{% block head %}
<meta charset="utf-8" />
{{super()}}
{% endblock %}
{% block body %}
<h1>Hello, {{ name }}!</h1>
{% endblock %}

參考資料:

歡迎關注我的其它發布渠道