文 / 秦未
1.jinja2解析
今天學(xué)習(xí)Flask的模板引擎 -- jinja2重虑,我們先看看它工作的原理:
說明:視圖函數(shù)通過上下文與模板之間傳遞數(shù)據(jù)秦士,模板由jinja2引擎驅(qū)動(dòng)支持并生成HTML文件永高,這樣展示在客戶端瀏覽器中的內(nèi)容就是完整的頁(yè)面了命爬。
我們之前有一個(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)于頁(yè)面</title>
</head>
<body>
{{ text }}
</body>
</html>
運(yùn)行輸出:
其中我們發(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)于頁(yè)面</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)于頁(yè)面</title>
</head>
<body>
{{ text|safe }}
</body>
</html>
說明:在指定值后面加 “|safe”督怜,即可在這個(gè)值中禁用自動(dòng)轉(zhuǎn)義。
最后效果是一樣的:
第二種方法其實(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解析庫(kù)是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)于頁(yè)面</title>
</head>
<body>
{{ text|safe }}
{{ body|md|safe }}
</body>
</html>
運(yùn)行效果:
有時(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)于頁(yè)面</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)行效果:
---end---