Flask模板引擎:Jinja2常用語(yǔ)法整理

摘要:Flask允悦,Jinja2汁咏,HTML

Flask模板引擎Jinja2簡(jiǎn)述

模板實(shí)質(zhì)上是一個(gè)靜態(tài)的包含HTML語(yǔ)法的全部或片段的文本文件贝咙,也可以包含變量表示的動(dòng)態(tài)部分样悟。使用真實(shí)值替換網(wǎng)頁(yè)模板中的變量,生成對(duì)應(yīng)數(shù)據(jù)的HTML片段庭猩,這一過(guò)程稱為渲染窟她,F(xiàn)alsk使用Jinja2模板引擎來(lái)渲染模板,簡(jiǎn)單而言Jinja2就是一種基于Python的在HTML代碼中對(duì)動(dòng)部分進(jìn)行一系列操作的語(yǔ)法蔼水。
Flask中使用render_template來(lái)渲染模板震糖,render_template的首個(gè)入?yún)⑹悄0逦募拿Q,F(xiàn)alsk會(huì)從項(xiàng)目根目錄下的templates目錄下查找模版趴腋。先創(chuàng)建一個(gè)first.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>這是一個(gè)測(cè)試</title>
</head>
<body>
    <p>這是一個(gè)測(cè)試</p>
</body>
</html>

在視圖函數(shù)中使用render_template渲染模板

from flask import render_template

@app.route('/template_test')
def template_test():
    return render_template('first.html')

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5000)

向模板中傳遞參數(shù)

Flask可以將程序中的參數(shù)或變量傳入指定的模板進(jìn)行渲染吊说,在HTML文件中使用{{ }}將程序中指定的參數(shù)進(jìn)行傳入。修改first.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>這是一個(gè)測(cè)試</title>
</head>
<body>
    <p>這是一個(gè)測(cè)試 {{ name }}</p>
</body>
</html>

在渲染方法render_template中傳入?yún)?shù)优炬,指定模板中動(dòng)態(tài)變量的名字等于程序中的參數(shù)名颁井,必須指定模板中的動(dòng)態(tài)變量名

@app.route('/template_test')
def template_test():
    my_name = "你好"
    return render_template('first.html', name=my_name)

傳入多個(gè)變量可以直接使用**locals()方法,此時(shí)模板中動(dòng)態(tài)變量的名稱要和程序中的參數(shù)名稱一致蠢护,如下修改視圖函數(shù)

@app.route('/template_test')
def template_test():
    name = "你好"
    return render_template('first.html', **locals())

Jinja2控制語(yǔ)句

Jinja2中的控制語(yǔ)句用來(lái)控制渲染的方向雅宾,使用iffor關(guān)鍵字葵硕,放在{%%}使用

if控制語(yǔ)句

if控制語(yǔ)句的基礎(chǔ)語(yǔ)法

{% if condition %}
    <p>do something</p>
{% else %}
    <p>do something</p>
{% endif %}

編寫(xiě)一個(gè)HTML其中通過(guò)判斷變量name在程序中是否存在來(lái)呈現(xiàn)不同的展示結(jié)果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>這是一個(gè)測(cè)試</title>
</head>
<body>
    {% if name %}
        <p>存在name</p>
    {% else %}
        <p>不存在name</p>
    {% endif %}
</body>
</html>

在視圖函數(shù)中將name注釋掉眉抬,此時(shí)不存在name程序變量,返回頁(yè)面結(jié)果為"不存在name"懈凹。

@app.route('/template_test')
def template_test():
    # name = "你好"
    return render_template('first.html', **locals())

多個(gè)分支條件判斷

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>這是一個(gè)測(cè)試</title>
</head>
<body>
    {% if age == 1 %}
        <p>age為1</p>
    {% elif age == 2 %}
        <p>age為2</p>
    {% else %}
        <p>age不為1和2</p>
    {% endif %}
</body>
</html>

組合判斷邏輯蜀变,支持python and or

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>這是一個(gè)測(cè)試</title>
</head>
<body>
    {% if age >= 1 and age < 3 %}
        <p>age為[1, 3)</p>
    {% elif age >= 3 and age < 4 %}
        <p>age為[3, 4)</p>
    {% else %}
        <p>age為其他</p>
    {% endif %}
</body>
</html>

可以在html標(biāo)簽中使用jinja2控制語(yǔ)句,實(shí)現(xiàn)不同條件不同樣式的按鈕

{% for cate in category_list %}
    <button {% if cate[0]== category %} class="categoryButton1" {% else %} class="categoryButton2" {% endif %}
            onclick="window.location.href='rank?category={{ cate[0] }}'">{{ cate[1] }}
    </button>
{% endfor %}
按鈕標(biāo)簽不同樣式.png
for控制語(yǔ)句

for控制語(yǔ)句的基礎(chǔ)語(yǔ)法

{% for 目標(biāo) in 對(duì)象 %}
    <p>do something</p>
{% endfor %}

Jinja2的for循環(huán)變量不需要{{ }}傳入介评,不支持continue和break库北,但是和Python一樣可以對(duì)Python的可迭代對(duì)象進(jìn)行循環(huán)遍歷。在一個(gè)循環(huán)代碼塊內(nèi)部調(diào)用loop的屬性可以獲得循環(huán)中的狀態(tài)數(shù)據(jù),比如可以一邊循環(huán)一邊拿到下標(biāo)贤惯,包括

loop.index: 當(dāng)前迭代的索引(從1開(kāi)始)
loop.index0: 當(dāng)前迭代的索引(從0開(kāi)始)
loop.first: 是否是第一次迭代,返回True棒掠,F(xiàn)alse
loop.last: 是否是最后一次迭代孵构,返回True,F(xiàn)alse
loop.length: 返回序列長(zhǎng)度

在HTML中構(gòu)建一個(gè)for循環(huán)語(yǔ)句烟很,每一次循環(huán)的對(duì)象是一個(gè)字段颈墅,使用.key直接拿到value值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>這是一個(gè)測(cè)試</title>
</head>
<body>
    {% for good in goods %}
        <p>{{ good.name }}</p>
        <p>{{ good.price }}</p>
    {% endfor %}
</body>
</html>

在視圖函數(shù)中創(chuàng)建一個(gè)字典對(duì)象傳入模板

@app.route('/template_test')
def template_test():
    goods = [{"name": "蘋(píng)果", "price": 32}, {"name": "橘子", "price": 99}]
    return render_template('first.html', **locals())

也可以使用Python字段的語(yǔ)法拿到值

    {% for good in goods %}
        <p>{{ good["name"] }}</p>
        <p>{{ good["price"] }}</p>
    {% endfor %}

在代碼塊中使用loop關(guān)鍵字

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>這是一個(gè)測(cè)試</title>
</head>
<body>
    {% for good in goods %}
        <p>{{ good.name }}</p>
        <p>{{ good.price }}</p>
        <p>循環(huán)長(zhǎng)度{{ loop.length }}</p>
        <p>當(dāng)前索引{{ loop.index0 }}</p>
        <p>是否結(jié)束{{ loop.last }}</p>
    {% endfor %}
</body>
</html>
查看循環(huán)展示結(jié)果.png

Python中的range可以結(jié)合for循環(huán)一起使用,在jinja2中也可以直接使用

    {% for i in range(20) %}
        <p>{{ i }}</p>
    {% endfor %}

Jinja2的過(guò)濾器

過(guò)濾器的本質(zhì)是一個(gè)轉(zhuǎn)換函數(shù)雾袱,有時(shí)候不僅需要輸出程序參數(shù)還要對(duì)參數(shù)進(jìn)行修改轉(zhuǎn)換才能輸出恤筛,此時(shí)需要用到過(guò)濾器,過(guò)濾器寫(xiě)在變量后面芹橡,中間用|隔開(kāi)毒坛,|左右沒(méi)有空格

字符串過(guò)濾器
  • default: 如果程序中沒(méi)有該參數(shù)則可以輸出一個(gè)默認(rèn)值,如果程序中存在該參數(shù)林说,但是是None煎殷,""0腿箩,False豪直,可以設(shè)置第二個(gè)參數(shù),如果設(shè)為true則以上0值輸出也跳轉(zhuǎn)到默認(rèn)值珠移,false則保留原始空值輸出弓乙,默認(rèn)不寫(xiě)的話就是false
<p>{{ name|default('小明', true)}}</p>

這個(gè)過(guò)濾器也可以用or關(guān)鍵字實(shí)現(xiàn),和Python語(yǔ)法一致钧惧,如果前項(xiàng)為空輸出后項(xiàng)暇韧,無(wú)此參數(shù)和有參數(shù)但是為空都會(huì)走or邏輯

<p>{{ name or '小明'}}</p>

  • replace: 替換,和Python語(yǔ)法一致浓瞪,多個(gè)過(guò)濾器可以連續(xù)寫(xiě)
<p>{{ name|default('小明')|replace('小', '大')}}</p>
  • trim: 去除收尾空格
<p>{{ '   去除收尾空格   '|trim }}</p>
  • ~:字符串連接锨咙,傳入name='小明',輸出"我和小明出去玩了"
<p>{{ '我和'~name~'出去玩了'}}</p>

可迭代對(duì)象過(guò)濾器
  • firstlast:獲得列表的第一個(gè)和最后一個(gè)元素
    <p>第一個(gè)元素{{ items|first }}</p>
    <p>最后一個(gè)元素{{ items|last }}</p>

在視圖函數(shù)中傳遞一個(gè)列表

@app.route('/template_test')
def template_test():
    items = [1, 3, 5, 7, 9]
    return render_template('first.html', **locals())

輸出為"第一個(gè)元素1 最后一個(gè)元素9"

  • count: 返回列表的長(zhǎng)度
<p>列表長(zhǎng)度{{ items|count }}</p>
  • max追逮,min求一個(gè)列表的最大最小值
<p>{{ ent_scores|max }}</p> 
<p>{{ ent_scores|min }}</p>
  • join:列表轉(zhuǎn)字符串酪刀,和Python語(yǔ)法一致,可以指定分隔符钮孵,輸出為"列表轉(zhuǎn)字符串1,3,5,7,9"
<p>列表轉(zhuǎn)字符串{{ items|join(',') }}</p>
  • sort:排序骂倘,默認(rèn)不傳參是正序排序,傳入reverse=true是降序
<p>列表升序{{ items|sort }}</p>
<p>列表降序{{ items|sort(true) }}</p>

可以指定屬性排序巴席,比如需要排序的對(duì)象是一個(gè)字典集合

items = [{"name": "蘋(píng)果", "price": 23}, {"name": "西瓜", "price": 33}, {"name": "西紅柿", "price": 25}]

為sort過(guò)濾器增加attribute字段指定排序?qū)傩岳裕Ч缦?/p>

    <p>根據(jù)某個(gè)屬性排序{{ items|sort(attribute='price', reverse=true) }}</p>
    {% for item in items|sort(attribute='price', reverse=true) %}
        <p>{{ item.name }}</p>
    {% endfor %}
指定屬性排序.png
  • reverse: 可迭代對(duì)象反轉(zhuǎn),字符串和集合都可以
<p>{{ '12345'|reverse }}</p>
<p>{{ [1, 2, 3, 4, 5]|reverse|join(',')}}</p>
數(shù)值對(duì)象過(guò)濾器
  • round: 保留小數(shù),比如保留2為小數(shù)
<p>{{ 2.222|round(2) }}</p>
  • string:轉(zhuǎn)化為字符串荧库,如果程序傳入的參數(shù)是數(shù)值堰塌,在模板中需要進(jìn)行字符串操作需要轉(zhuǎn)string
<p>{{ 2.22|string + '你好'}}</p>
  • int:轉(zhuǎn)化為整數(shù),向下取整
<p>{{ 2.222|int }}</p>
  • abs: 轉(zhuǎn)化為絕對(duì)值
<p>{{ -2.222|abs }}</p>
  • -:直接取負(fù)號(hào)分衫,取相反數(shù)场刑,如下num輸入為3,最終輸出為0
<p>{{ -num + 3}}</p>

其他jinja2的內(nèi)置過(guò)濾器參考http://www.pythontip.com/blog/post/5455/


過(guò)濾器的執(zhí)行順序

如果一個(gè){{ }}表達(dá)式中既存在過(guò)濾器蚪战,又存在Python的基本語(yǔ)句牵现,如運(yùn)算,其他關(guān)鍵字等邀桑,過(guò)濾器總是和他之前緊貼的那個(gè)元素相連瞎疼,即過(guò)濾器優(yōu)先級(jí)最高,因此必要的時(shí)候需要使用( )來(lái)控制過(guò)濾器的范圍壁畸,比如

{{ (ent_rank * 100)|int ~"%"}}

如果不加入括號(hào)贼急,則對(duì)ent_rank int取整無(wú)效,因?yàn)樗粚?duì)100有效

自定義過(guò)濾器

可以自己用Python語(yǔ)言實(shí)現(xiàn)一個(gè)自定義過(guò)濾器使用add_template_filter進(jìn)行注冊(cè)調(diào)用捏萍,或者使用修飾器template_filter注冊(cè)

@app.template_filter('t_func')
def t_func(t):
    t2 = time.time()
    diff = t2 - t
    if diff < 60:
        return "剛剛"
    elif 60 <= diff < 60 * 60:
        return "%d分鐘之前" % int(diff / 60)
    elif 3600 <= diff < 3600 * 24:
        return "%d小時(shí)之前" % int(diff / 3600)
    else:
        return "很久之前"

另一種注冊(cè)方式

def t_func(t):
    t2 = time.time()
    diff = t2 - t
    if diff < 60:
        return "剛剛"
    elif 60 <= diff < 60 * 60:
        return "%d分鐘之前" % int(diff / 60)
    elif 3600 <= diff < 3600 * 24:
        return "%d小時(shí)之前" % int(diff / 3600)
    else:
        return "很久之前"

app.add_template_filter(t_func, 't_func')

HTML模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>這是一個(gè)測(cè)試</title>
</head>
<body>
    <p>文章發(fā)表于{{ t| t_func }}</p>
</body>
</html>

最終顯示結(jié)果為"文章發(fā)表于很久之前"
自定義過(guò)濾器可以帶有一個(gè)或者多個(gè)參數(shù)竿裂,函數(shù)的第一個(gè)參數(shù)作為需要渲染轉(zhuǎn)化的參數(shù),后面的參數(shù)可以在過(guò)濾器括號(hào)中指定作為輔助參數(shù)照弥,比如

def score_grade(score: int, add: str):
    if score >= 90:
        return "高風(fēng)險(xiǎn)" + add
    elif 90 > score >= 80:
        return "中度風(fēng)險(xiǎn)" + add
    elif 80 > score >= 60:
        return "低風(fēng)險(xiǎn)" + add
    elif 60 > score:
        return "良好" + add

detail.add_app_template_filter(score_grade, 'score_grade')

以上函數(shù)除了要轉(zhuǎn)化的score腻异,還增加一個(gè)可變參數(shù),在模板中的使用这揣,過(guò)濾器后面使用( )傳遞參數(shù)悔常,如果要傳遞的參數(shù)也是需要渲染的變量,不需要再加{{ }}给赞,在外{{ }}內(nèi)整體渲染

<p style="font-family: 楷體; font-size: 20px;">風(fēng)險(xiǎn)等級(jí): 風(fēng)險(xiǎn)等級(jí)為{{ ent_score|score_grade('aaa') }}</p>
帶有參數(shù)的過(guò)濾器.png

Jinja2編寫(xiě)宏和導(dǎo)入應(yīng)用宏

宏類似函數(shù)机打,將一個(gè)邏輯塊中變動(dòng)的部分單獨(dú)抽出來(lái)作為參數(shù),其他固定的部分包裝在一個(gè)程序塊中片迅,jinja2中定義宏的關(guān)鍵字是macro残邀。如下在html中定義一個(gè)宏input,有name柑蛇,type芥挣,value三個(gè)參數(shù),后面兩個(gè)參數(shù)有默認(rèn)值耻台,這三個(gè)參數(shù)對(duì)應(yīng)h5的input的標(biāo)簽空免,實(shí)際上就是用一個(gè)宏實(shí)現(xiàn)了多種樣式的input標(biāo)簽。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>這是一個(gè)測(cè)試</title>
</head>
<body>
{% macro input(name, type='text', value='') %}
    <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
{% endmacro %}

<p>用戶名:{{ input('username') }}</p>
<p>密碼:{{ input('password', type='password') }}</p>
<p>用戶名:{{ input('submit', type='submit', value='提交') }}</p>
</body>
</html>

定義好宏之后盆耽,使用{{ 宏(參數(shù)) }}進(jìn)行調(diào)用蹋砚,效果如下

宏的定義和調(diào)用.png


一個(gè)宏可以被多個(gè)h5模板導(dǎo)入使用扼菠,所以需要將所有的宏寫(xiě)在一個(gè)h5中,導(dǎo)入的方法類似Python的import坝咐。首先新建一個(gè)h5命名為macro.html

{% macro input(name, type='text', value='') %}
    <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
{% endmacro %}

在另一個(gè)模板中導(dǎo)入

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>這是一個(gè)測(cè)試</title>
</head>
<body>
{% import 'macro.html' as macro %}
<p>用戶名:{{ macro.input('username') }}</p>
<p>密碼:{{ macro.input('password', type='password') }}</p>
<p>用戶名:{{ macro.input('submit', type='submit', value='提交') }}</p>
</body>
</html>

也可以直接從模板中導(dǎo)入宏循榆,使用from import導(dǎo)入

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>這是一個(gè)測(cè)試</title>
</head>
<body>
{% from 'macro.html' import input %}
<p>用戶名:{{ input('username') }}</p>
<p>密碼:{{ input('password', type='password') }}</p>
<p>用戶名:{{ input('submit', type='submit', value='提交') }}</p>
</body>
</html>

include的使用

jinja2中將一個(gè)模板引入到另一個(gè)模板的指定位置使用關(guān)鍵字include,比如引入公共部分墨坚,header.html秧饮,footer.html等,先創(chuàng)建公共頭部和尾部的h5框杜,include導(dǎo)入的模板必須在templates目錄下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>header</title>
</head>
<body>
<div class="header">
    這是網(wǎng)頁(yè)頭部
</div>

</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>footer</title>
</head>
<body>
<div class="footer">
    這是網(wǎng)頁(yè)尾部
</div>

</body>
</html>

另外編寫(xiě)一個(gè)模塊浦楣,使用include導(dǎo)入header.html和footer.html袖肥,在主模板中定義的css樣式可以被include導(dǎo)入的模板使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>這是一個(gè)測(cè)試</title>
    <style type="text/css">
        .header{
            width:100%;
            height:40px;
            border: 1px solid #A52A2A;
        }
        .footer{
            width:100%;
            height:40px;
            border: 1px solid #8A2BE2;
        }
        .content{
            width:100%;
            height:40px;
            border: 1px solid #e2e2e2;
        }
    </style>
</head>
<body>
{% include "header.html" %}
<div class="content">
    這是正文
</div>
{% include "footer.html" %}
</body>
</html>

效果如下


include導(dǎo)入模板.png

使用set和with賦值變量

jinja2中setwith都可以對(duì)變量進(jìn)行定義和賦值咪辱,set定義的在整個(gè)模板范圍中都有效,with定義的變量有作用范圍椎组,with的作用就是定義這個(gè)范圍油狂,分別用set和with定義變量如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>這是一個(gè)測(cè)試</title>
</head>
<body>
{% set a='123' %}

<p>set的值{{ a }}</p>
{% with b='321' %}
    <p>with的值{{ b }}</p>
{% endwith %}
</body>
</html>

調(diào)用定義的值使用{% %},如果在with外面調(diào)用在with內(nèi)部定義的值則無(wú)效
如果在一個(gè)with語(yǔ)句中存在需要需要渲染的變量則直接寫(xiě)入變量名寸癌,不需要再加渲染花括號(hào)专筷,如果with語(yǔ)句中有多個(gè)變量需要定義,中間用逗號(hào)隔開(kāi)蒸苇,如下

{% with ent_score_diff = ent_scores[-1] - ent_scores[0], ent_max_min_diff = ent_scores|max - ent_scores|min %}

靜態(tài)文件的加載 url_for

需要先創(chuàng)建static文件夾磷蛹,再創(chuàng)建子文件夾cssjs溪烤,images味咳,同時(shí)需要使用url_for函數(shù)。

(1)導(dǎo)入js
<script src="{{ url_for('static', filename='js/tmp.js') }}"></script>

也可以使用更通用額方式

<script type="text/javascript" src="static/js/tmp.js"></script>
(2)導(dǎo)入圖片
 <img src="{{ url_for('static', filename='images/index.jpeg')}}" width="1700" height="350">
(3)導(dǎo)入css
<link rel="stylesheet" href="{{ url_for('static', filename='css/car.css') }}" />

模板的集成extends

一個(gè)系統(tǒng)的網(wǎng)站每個(gè)網(wǎng)頁(yè)需要有統(tǒng)一的結(jié)構(gòu)檬嘀,比如每個(gè)網(wǎng)頁(yè)都有標(biāo)題槽驶,內(nèi)容,底部等幾個(gè)部分鸳兽,模板繼承的目的就是將相同的部分提取出來(lái)掂铐,形成一個(gè)base.html。在jinja2中使用extends關(guān)鍵字揍异。
模板的繼承包含基本模板子模板全陨,子模板繼承基本模板,基本模板包含了基本骨架衷掷,其中有一些空的不完善的塊block需要子模板來(lái)填充烤镐,不同的block之間用不同的名字區(qū)分,因此每個(gè)block還需要定義一個(gè)名字棍鳖,比如父模板如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
{% block body%}
    <p>這是基礎(chǔ)身體</p>
{% endblock %}
{% block footer %}
    <p>這是尾巴</p>
{% endblock %}
</body>
</html>

在新模板中繼承炮叶,繼承骨架重寫(xiě)title碗旅,body,footer三個(gè)block镜悉,其中{{ super() }}方法是使得基礎(chǔ)框架中原有的block內(nèi)的內(nèi)容保留祟辟,默認(rèn)子模板中的block代碼會(huì)把基礎(chǔ)模塊中的對(duì)應(yīng)的block代碼覆蓋。

{% extends "base.html" %}
{% block title%}這是繼承的title{% endblock %}
{% block body %}
    {{ super() }}
    <p>繼承的身體</p>
{% endblock %}
{% block footer %}
    <p>繼承的尾巴</p>
{% endblock %}

效果如下


模板繼承.png

Jinja2的空白控制

在最終輸出的網(wǎng)頁(yè)HTML中侣肄,Jinja2中的表達(dá)式會(huì)保留移除后的空行旧困,比如如果模板代碼如下

<div>
    {% if True %}
        yay
    {% endif %}
</div>

最終在瀏覽器看到的網(wǎng)頁(yè)源代碼是

<div>
 
        yay
 
</div>

這是由于Jinja2表達(dá)式留下的空行和jinja2的縮進(jìn)導(dǎo)致的,但是多余的空白不影響瀏覽器的解析稼锅,卻影響HTML文件體積大小吼具,降低數(shù)據(jù)傳輸速度,因此在代碼部署前需要去除空格空行矩距,對(duì)于縮進(jìn)沒(méi)有強(qiáng)制要求拗盒,但是為了代碼的可讀性,建議在HTML代碼中的Jinja2語(yǔ)句中加入縮進(jìn)锥债。
去除空格空行可以在Jinja2語(yǔ)句的分隔符的%旁邊加入減號(hào)-陡蝇,緊貼,沒(méi)有空格哮肚,比如

<div id="ent-1">
    {% for industry_ent in industry_ents[:5] %}
        <a href="/compare?ent1={{ ent_1 }}&ent2={{ industry_ent }}"><p class="subTitle" style="font-size: 15px;">{{ industry_ent }}</p></a>
    {% endfor %}
</div>

渲染之后的HTML代碼為


帶有空白的html.png

在分隔符中加入-號(hào)

<div id="ent-1">
    {% for industry_ent in industry_ents[:5] -%}
        <a href="/compare?ent1={{ ent_1 }}&ent2={{ industry_ent }}"><p class="subTitle" style="font-size: 15px;">{{ industry_ent }}</p></a>
    {%- endfor %}
</div>

起始語(yǔ)句-加載右邊登夫,帶有語(yǔ)句右邊的空白去除,結(jié)束語(yǔ)句-加載左邊允趟,說(shuō)明語(yǔ)句左邊的空白去除恼策,此時(shí)再看瀏覽器的源碼如下:


去除空白的html.png

另一種方法是在app中配置jinja的環(huán)境參數(shù),就不要在在Jinja2語(yǔ)法的時(shí)候時(shí)刻注意要寫(xiě)-號(hào)了

app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True

但是宏內(nèi)的空白不收這兩個(gè)環(huán)境參數(shù)控制潮剪,還是需要在宏分隔符中手動(dòng)加入-號(hào)涣楷,例如

{% macro score_grade_img(filename, width="250", height="220") %}
    <img src="{{ url_for('static', filename=filename) }}" width={{ width }} height={{ height }}>
{% endmacro %}

手動(dòng)加入-號(hào)

{% macro score_grade_img(filename, width="250", height="220") -%}
    <img src="{{ url_for('static', filename=filename) }}" width={{ width }} height={{ height }}>
{%- endmacro %}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市鲁纠,隨后出現(xiàn)的幾起案子总棵,更是在濱河造成了極大的恐慌,老刑警劉巖改含,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件情龄,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡捍壤,警方通過(guò)查閱死者的電腦和手機(jī)骤视,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)鹃觉,“玉大人专酗,你說(shuō)我怎么就攤上這事〉辽龋” “怎么了祷肯?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵沉填,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我佑笋,道長(zhǎng)翼闹,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任蒋纬,我火速辦了婚禮猎荠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蜀备。我一直安慰自己关摇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布碾阁。 她就那樣靜靜地躺著输虱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瓷蛙。 梳的紋絲不亂的頭發(fā)上悼瓮,一...
    開(kāi)封第一講書(shū)人閱讀 51,541評(píng)論 1 305
  • 那天戈毒,我揣著相機(jī)與錄音艰猬,去河邊找鬼。 笑死埋市,一個(gè)胖子當(dāng)著我的面吹牛冠桃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播道宅,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼食听,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了污茵?” 一聲冷哼從身側(cè)響起樱报,我...
    開(kāi)封第一講書(shū)人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泞当,沒(méi)想到半個(gè)月后迹蛤,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡襟士,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年盗飒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陋桂。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逆趣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嗜历,到底是詐尸還是另有隱情宣渗,我是刑警寧澤抖所,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站痕囱,受9級(jí)特大地震影響部蛇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜咐蝇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一涯鲁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧有序,春花似錦抹腿、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至盅称,卻和暖如春肩祥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背缩膝。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工混狠, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人疾层。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓将饺,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親痛黎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子予弧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容