包括這 3 個模板語言在內,Python 積累了許多模板語言。html
當須要使用模板語言來編寫 Python Web 應用時,有不少健壯的解決方案。python
有 Jinja2、Genshi 和 Mako。甚至還有 Chameleon 之類的解決方案,雖然有些陳舊,但仍被 Pyramid 框架推薦。react
Python 已經存在了很長時間。此時,在系統的深處,它積累了一些幾乎被遺忘的模板語言,它們都是值得一試的。linux
這些語言就像桉樹上可愛的考拉同樣,在本身的生態圈裏快樂地生活着,有時也會有危險的工做,這些都是不多有人據說過的模板語言,使用過的應該更少。git
你是否曾經想過:「如何得到一種沒有任何特性的模板語言,並且同時也不須要 pip install
安裝任何東西?」 Python 標準庫已經爲你提供了答案。雖然沒有循環和條件,但 string.Template
類是一種最小的模板語言。github
使用它很簡單。web
>>> import string
>>> greeting = string.Template("Hello, $name, good $time!")
>>> greeting.substitute(name="OpenSource.com", time="afternoon")
'Hello, OpenSource.com, good afternoon!'
複製代碼
你會給一個一應俱全的庫送什麼禮物?bash
固然,不是模板語言,由於它已經有了。twisted.web.template 中嵌套了兩種模板語言。一種是基於 XML 的,並有一個很棒的文檔。框架
可是它還有另外一種,一種基於使用 Python 做爲領域特定語言(DSL)來生成 HTML 文檔。異步
它基於兩個原語:包含標籤對象的 twisted.web.template.tags
和渲染它們的 twisted.web.template.flattenString
。因爲它是 Twisted 的一部分,所以它內置支持高效異步渲染。
此例將渲染一個小頁面:
async def render(reactor):
my_title = "A Fun page"
things = ["one", "two", "red", "blue"]
template = tags.html(
tags.head(
tags.title(my_title),
),
tags.body(
tags.h1(my_title),
tags.ul(
[tags.li(thing) for thing in things],
),
tags.p(
task.deferLater(reactor, 3, lambda: "Hello "),
task.deferLater(reactor, 3, lambda: "world!"),
)
)
)
res = await flattenString(None, template)
res = res.decode('utf-8')
with open("hello.html", 'w') as fpout:
fpout.write(res)
複製代碼
該模板是使用 tags.<TAGNAME>
來指示層次結構的常規 Python 代碼。原生支持渲染字符串,所以任何字符串都正常。
要渲染它,你須要作的是添加調用:
from twisted.internet import task, defer
from twisted.web.template import tags, flattenString
def main(reactor):
return defer.ensureDeferred(render(reactor))
複製代碼
最後寫上:
task.react(main)
複製代碼
只需 3 秒(而不是 6 秒),它將渲染一個不錯的 HTML 頁面。在實際中,這些 deferLater
能夠是對 HTTP API 的調用:它們將並行發送和處理,而無需付出任何努力。我建議你閱讀關於更好地使用 Twisted。不過,這已經能夠工做了。
你會說:「可是 Python 並非針對 HTML 領域而優化的領域特定語言。」 若是有一種語言能夠轉化到 Python,可是更適合定義模板,而不是像 Python 那樣按原樣解決呢?若是能夠的話,請使用「Python 模板語言」(PTL)。
編寫本身的語言,有時被說成是一個攻擊假想敵人的唐吉坷德項目。當 Quixote(可在 PyPI 中找到)的創造者決定這樣作時,並無受此影響。
如下將渲染與上面 Twisted 相同的模板。警告:如下不是有效的 Python 代碼:
import time
def render [html] ():
my_title = "A Fun page"
things = ["one", "two", "red", "blue"]
"<html><head><title>"
my_title
"</head></title><body><h1>"
my_title
"</h1>"
"<ul>"
for thing in things:
"<li>"
thing
"</li>"
"<p>"
time.sleep(3)
(lambda: "Hello ")()
time.sleep(3)
(lambda: "world!")()
"</p>"
"</body></html>"
def write():
result = render()
with open("hello.html", 'w') as fpout:
fpout.write(str(result))
複製代碼
可是,若是將它放到 template.ptl
文件中,那麼能夠將其導入到 Quixote 中,並寫出能夠渲染模板的版本:
>>> from quixote import enable_ptl
>>> enable_ptl()
>>> import template
>>> template.write()
複製代碼
Quixote 安裝了一個導入鉤子,它會將 PTL 文件轉換爲 Python。請注意,此渲染須要 6 秒,而不是 3 秒。你再也不得到自由的異步性。
Python 庫的歷史悠久且曲折,其中一些庫能夠或多或少都能達到相似結果(例如,Python 包管理)。
我但願你喜歡探索這三種能夠用 Python 建立模板的方式。另外,我建議從這三個庫之一開始瞭解。
你是否有另外一種深奧的模板方法?請在下面的評論中分享!
via: opensource.com/article/20/…
做者:Moshe Zadka 選題:lujun9972 譯者:geekpi 校對:wxy