theme: channing-cyan
Jinja2采用100%python代码实现,是一个现代的,设计者友好的,仿照 Django 模板的 Python 模板语言。 它速度快,被广泛使用,并且提供了可选的沙箱模板执行环境保证安全。是python界最主流的模板引擎,星星数10k+一、环境准备
1.fastapi初始化jinja
from fastapi.templating import Jinja2Templates
# 模板初始化
jinjaEngine = Jinja2Templates(
"template"
)
把当前目录的template文件夹作为模板引擎根目录
2.修改Jinja2的定界符
默认情况jinja是以下语法
控制结构 {% %}
变量取值 {{ }}
注释 {# #}
这个{{}}获取变量的方式,会和vue的语法冲突。所以我们需要改变这个默认的语法
custom_delimiters = {
"variable_start_string": "[[",
"variable_end_string": "]]",
"block_start_string": "[%",
"block_end_string": "%]",
"comment_start_string": "[#",
"comment_end_string": "#]",
}
from fastapi.templating import Jinja2Templates
# 模板初始化
jinjaEngine = Jinja2Templates(
"template", **custom_delimiters
)
3.jinja空行去除
默认在使用语法时候会多很多的空行,比如{% %} 在解析时候会认为占位一行。需要去掉默认生成规则
from fastapi.templating import Jinja2Templates
# 模板初始化
jinjaEngine = Jinja2Templates(
"template", trim_blocks=True, lstrip_blocks=True, **custom_delimiters
)
二、jinja的常用操作
1.使用宏复用
很多代码尤其是可能在多处使用的函数或相似的布局可以封装起来。一个好的思路就是把布局作为一个函数输出的结果
template/macro/_macros.html
[% macro user_card(list, show_bio=True) %]
<div class="user-card">
[[ show_bio ]]
[% if show_bio %]
daxin is safe.
[% endif %]
[# for循环 #]
<ul>
[% for item in list %]
<li>[[item]]</li>
[% endfor %]
</ul>
</div>
[% endmacro %]
[# 引入宏模板 #]
[% import 'macro/_macros.html' as macros %]
[# 使用宏模板 #]
[[ macros.user_card(list) ]]
2.使用继承模板
类似前端的插槽,telport机制。做到一个布局占位的目的
template/extend/base.html
<!DOCTYPE html>
<html>
<head>
<title>[% block title %]Default Title[% endblock %]</title>
</head>
<body>
[% block content %]Default Content[% endblock %]
</body>
</html>
[# 引入继承模板 #]
[% extends "extend/base.html" %]
[# 替换继承模板 #]
[% block title %]Custom Title[% endblock %]
3.原生编译
[% raw %]
let arr =[[1],[2]]
[% endraw %]
在这里面的内容不会受到jinja的引擎控制,原样输出
三、jinja在fastapi中的使用方式
template/1.html
[% extends "extend/base.html" %]
[# 引入宏模板 #]
[% import 'macro/_macros.html' as macros %]
[# 替换继承模板 #]
[% block title %]Custom Title[% endblock %]
[% block content %]
[# 变量使用,首字母大写 #]
[[ username|capitalize ]]
[[ macros.user_card(list) ]]
[[arr]]
[# 原生编译 #]
[% raw %]
let arr =[[1],[2]]
[% endraw %]
[% endblock %]
1. jinja 到浏览器
@app.get("/html")
def html(request: Request, username: str = ''):
list = ["音乐", "游戏", "编码"]
content = jinjaEngine.TemplateResponse(
"1.html", {"request": request, "username": username, "list": list}
)
return content
2. jinja到文件
@app.get("/render")
def render():
content = {"username": "larry", "list": ["音乐", "游戏", "编码"]}
template = jinjaEngine.get_template("1.html")
template.stream(content).dump("template/new_file.html")
return content
注意生成的目录需要自己先确保存在,jinja不会帮忙创建
3. jinja原生api
from jinja2 import Template
@router.get("/renderStr")
def renderStr():
template_str = """
<p>Hello, {{ name }}!
You have {{ num }} new messages.</p>
"""
data = {
"name": "Larry",
"num": 3,
}
template=Template(template_str)
return template.render(data)
运行项目,打开loclahost:8000/html 和 loclahost:8000/render等查看结果