Flask學(xué)習(xí)日志(六) - Flask模板

每日壁紙.jpg

文 / 秦未

1.jinja2解析

今天學(xué)習(xí)Flask的模板引擎 -- jinja2,我們先看看它工作的原理:

jinja2工作原理.png

說明:視圖函數(shù)通過上下文與模板之間傳遞數(shù)據(jù),模板由jinja2引擎驅(qū)動(dòng)支持并生成HTML文件,這樣展示在客戶端瀏覽器中的內(nèi)容就是完整的頁面了。

我們之前有一個(gè)范例:

@app.route('/about')
def about():
    return '<h1>about</h1>'

我們改變一下:

@app.route('/about')
def about():
    return render_template('blog/about.html', **{
        'text': 'Hello, World',
    })

其中about.html內(nèi)容 :

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>關(guān)于頁面</title>
</head>
<body>

{{ text }}

</body>
</html>

運(yùn)行輸出:

運(yùn)行狀態(tài)1.png

其中我們發(fā)現(xiàn)h1并沒有生效,而是作為字符串完整的顯示了出來,其實(shí)這是jinja2的自動(dòng)轉(zhuǎn)義功能在起作用,主要目的是防止跨站腳本攻擊。

但如果我們能保證內(nèi)容是安全的,我們想要實(shí)現(xiàn)標(biāo)簽的作用該怎么辦呢?

jinja2提供兩種辦法禁用自動(dòng)轉(zhuǎn)義功能。

1.塊元素包裹內(nèi)容:

{#/app/templates/blog/about.html#}
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>關(guān)于頁面</title>
</head>
<body>

{% autoescape false%}
{{ text }}
{% endautoescape %}

</body>
</html>

說明:在{% autoescape false%}{% endautoescape %}內(nèi)包裹的所有內(nèi)容都會(huì)被禁止自動(dòng)轉(zhuǎn)義。

2.單獨(dú)的

{#/app/templates/blog/about.html#}
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>關(guān)于頁面</title>
</head>
<body>

{{ text|safe }}

</body>
</html>

說明:在指定值后面加 “|safe”,即可在這個(gè)值中禁用自動(dòng)轉(zhuǎn)義。

最后效果是一樣的:

運(yùn)行效果2.png

第二種方法其實(shí)是模板引擎的過濾器,本質(zhì)來說這是一種值的預(yù)處理方法(函數(shù)),每一個(gè)過濾器代表一個(gè)方法(函數(shù)),它接收|之前的參數(shù),然后輸出內(nèi)容在當(dāng)前位置,在模板中一個(gè)變量可同時(shí)使用多個(gè)過濾器,解析從左往右。

jinja2本身提供了相當(dāng)多的過濾器,正常情況下足夠我們使用了,當(dāng)然我們也可以自定義過濾器。

2.自定義過濾器示例:

我們需要一個(gè)markdown過濾器,官方并沒有提供。

首先下載一個(gè)mistune模塊,這個(gè)markdown解析庫是Python中最快的,據(jù)稱比Markdown模塊快10倍左右。

pip install mistune

然后在app.py 內(nèi)增加一個(gè)裝飾器加函數(shù):

# /app/app.py
@app.template_filter('md')
def markdown_to_html(text):
    import mistune
    markdown = mistune.Markdown()
    return markdown(text)

同時(shí)為了驗(yàn)證,修改about函數(shù):

# /app/app.py
@app.route('/about')
def about():
    return render_template('blog/about.html', **{
        'text': '<h1>Hello, World</h1>',
        'body': '## 演示'
    })

about.html也要修改:

{#/app/templates/blog/about.html#}
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>關(guān)于頁面</title>
</head>
<body>

{{ text|safe }}
{{ body|md|safe }}
</body>
</html>

運(yùn)行效果:

運(yùn)行效果3.png

有時(shí)候,我們想在前臺(tái)運(yùn)行一個(gè)函數(shù)怎么辦?

比如我們想實(shí)現(xiàn)一個(gè)功能:定義一個(gè)函數(shù)讀取目錄下的md文件并輸出到前臺(tái)。

先看源碼:

# /app/app.py
def read_md(filename):
    from functools import reduce
    # 獲取當(dāng)前路徑
    basepath = path.abspath(path.dirname(__file__))
    # 將路徑連接
    upload_path = path.join(basepath, filename)
    with open(upload_path, encoding='UTF-8') as md_file:
        # reduce為歸納的意思,主要作用是讓獲取的每一行都加上前一行。
        content = reduce(lambda x, y: x + y, md_file.readlines())
    return content

# 將read_md函數(shù)傳遞到前臺(tái)
@app.context_processor
def inject_methods():
    return dict(read_md=read_md)

先建立一個(gè)在app目錄下的名叫md.md的文件:

![每日壁紙.jpg](http://upload-images.jianshu.io/upload_images/3980526-b9539b5712fcccee.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## 1.jinja2解析
今天學(xué)習(xí)Flask的模板引擎 -- jinja2,我們先看看它工作的原理:

使用:

{#/app/templates/blog/about.html#}
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>關(guān)于頁面</title>
</head>
<body>

{{ text|safe }}
{{ body|md|safe }}
{{ read_md('md.md')|md|safe }}

</body>
</html>

{{ read_md('md.md')|md|safe }}這段代碼從左往右執(zhí)行,先執(zhí)行這個(gè)函數(shù)read_md('md.md'),再將獲取的內(nèi)容轉(zhuǎn)換為HTML,同時(shí)這個(gè)內(nèi)容不需要轉(zhuǎn)義。

運(yùn)行效果:

運(yùn)行狀態(tài)4.png

---end---

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容