今天要来看 jinja 这个模板引擎。简单来说,它的功能就是在 HTML 里面执行一般程序,等等看过范例之後应该可以更清楚它的作用。
虽然说是在执行一般程序,但是其语法和一般程序也有一些些差别,我自己的习惯是照着一般程序的语法,如果错了的话再去搜寻正确的用法。
这次并非只需要简单地把程序码复制到 app.py
而已,我们需要先建立一个名为 templates
的资料夹,名字必须完全符合,等等会需要把 HTML 及以後会用到的 jinja 模板放在里面。
建立完资料夹後,我们来看看以下这份程序码,请注意 index.html
需要放在 templates
目录内。
app.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index_page():
name = "cat"
return render_template("index.html", username=name)
app.run(host="127.0.0.1", port=8080, debug=True)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Index</title>
</head>
<body>
{{ username }}
</body>
</html>
在 app.py
中,我们看到了一个新的函式:render_template
,不例外地,他也需要 import。它的功用是把一个 template 送入 jinja 跑,然後就可以得到一个字串,内容就是跑出来的 HTML,最後会把他 return 回去,这样一来,使用者就可以收到一个漂亮的 HTML,而非之前连 head
都没有的单纯内容。有了它的好处是,我们不需要把超长的 HTML 放在 python 档案里面,而且可以用比较漂亮的方式生出 HTML,等等在看 for
回圈的时候会更有感觉。
它需要一个 template name,以此处为例就是 index.html
。接下来会看到他後面的 username=name
,他会把刚刚定义的 name
传入 template 给 jinja 处理,而在 jinja 里面,他的名字叫做 username
。接着我们看到 index.html
,它里面有一行 {{ username }}
,在 jinja 里面,我们使用大括号来表示我们存取的变数,此处就是刚刚在 redner_template
传入的 name
。
这边值得注意的是,jinja 只会去处理大括号的部分,其他 HTML 的元素他秋毫无犯,会原汁原味秀出来。
刚刚看了基本的使用方法,现在来看看 if
要怎麽处理。
app.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index_page():
state = "running"
return render_template("index.html", state=state)
app.run(host="127.0.0.1", port=8080, debug=True)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Index</title>
</head>
<body>
{% if state == "running" %}
<p>running</p>
{% else %}
<p>terminated</p>
{% endif %}
</body>
</html>
我们这次传入了 state
这个变数,然後在 jinja 里面判断他是否等於 running
。这里要注意的是他 if 并不是跟刚刚一样用两个大括号,而是一个大括号和一个百分符号。这两种的差别在於他是不是一个 statement,{% %}
是给 statement 用的,而 {{ }}
则是用来存取内容用的。还有跟 python 不太一样的是他有 endif
,要记得加。也因为他已经有了 endif
,所以他不会管你的缩排。
还有一个要注意的是,我们的 <p>running</p>
和 <p>terminated</p>
并没有加上大括号,因为他就是一般的 HTML element。如果要把 running
换成 state
,那就要改成 <p>{{ state }}</p>
。
接下来就要讲回圈,比较特别的是 jinja 只有 for 没有 while,以下是一个范例。
app.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index_page():
users = ["Mary", "Cat", "Meow", "Harry"]
return render_template("index.html", users=users)
app.run(host="127.0.0.1", port=8080, debug=True)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Index</title>
</head>
<body>
<h1>User list</h1>
<ul>
{% for user in users %}
<li>{{ user | upper }} ({{ loop.index }})</li>
{% endfor %}
</ul>
</body>
</html>
在这个范例中我们传入了一个叫做 users
的 list,接下来我们交给 jinja 处理,他帮我们跑一个 for 回圈 (注意他也是 statement,所以要用 {% %}
),依序把 users
里的 user
取出来,然後放在 li
里面。接下来看到後面的 loop.index
,他是一个预设就存在的变数,他表示了平常在 list 看到的 index,但他是从 1
开始数,如果要从零开始数需要用 loop.index0
。
最後看到在 user
後面的 | upper
,他是一个 filter,就是等同於平常用到的 str.upper()
,只是在此处我们习惯使用 filter。在此处当然可以直接 {{ user.upper() }}
就好,但是有些时候没有办法用 python 的语法来处理,像是如果我们直接使用 int()
,他会告诉我们 undefined
,这时候就需要用 | int
来达成需求。
如果想要加入自定义的 filter 的话,flask 已经有一个包装好的方法可以处理,以下是范例。
app.py
from flask import Flask, render_template
app = Flask(__name__)
@app.template_filter()
def get_initial(s):
return s[0]
@app.route("/")
def index_page():
user = "Cat"
return render_template("index.html", user=user)
app.run(host="127.0.0.1", port=8080, debug=True)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Index</title>
</head>
<body>
{{ user | get_initial }}
</body>
</html>
可以看到在 app.py
的最前面我们使用了 app.template_filter
,让他装饰了一个会丢出第一个字母的函式,接下来在 index.html
我们就直接使用了这个 filter,不需要把它当成参数放在 render_template
,也不需要特别 import,他就直接变成了预设就存在的 filter。
Basic Syntax of Jinja
Python jinja2 + flask
Custom Jinja template filters in Flask
基於风险的方法已广泛用於各个领域,例如决策,审计,网络安全,银行等。“风险是不确定性对目标的影响。”...
爬虫完成後没发出通知,就像是黯然销魂饭少了洋葱 为什麽通知很重要? 在爬虫的运作完全自动化的状态下...
如何计算每一侦的位移 首先我们改写一下昨天的格式,还记得昨天我们用到的是这样的写法: cursorX...
今天也是跟昨天一样,要来练习比较难的题目,就是APCS啦,今天要来练习的题目是APCS 106年3月...
我想看标题一定会困惑这是什麽 先解释一下使用者最常用Excel作报表 然後想复制之後快速查询特定料号...