包括這 3 個模板語言在內,Python 積累了許多模板語言。
當需要使用模板語言來編寫 Python Web 應用時,有很多健壯的解決方案。
有 Jinja2、Genshi 和 Mako。甚至還有 Chameleon 之類的解決方案,雖然有些陳舊,但仍被 Pyramid 框架推薦。
Python 已經存在了很長時間。此時,在系統的深處,它積累了一些幾乎被遺忘的模板語言,它們都是值得一試的。
這些語言就像桉樹上可愛的考拉一樣,在自己的生態圈裡快樂地生活著,有時也會有危險的工作,這些都是很少有人聽說過的模板語言,使用過的應該更少。
你是否曾經想過:“如何獲得一種沒有任何特性的模板語言,而且同時也不需要 pip install
安裝任何東西?” Python 標準庫已經為你提供了答案。雖然沒有迴圈和條件,但 string.Template
類是一種最小的模板語言。
使用它很簡單。
>>> import string>>> greeting = string.Template("Hello, $name, good $time!")>>> greeting.substitute(name="OpenSource.com", time="afternoon")'Hello, OpenSource.com, good afternoon!'
你會給一個包羅萬象的庫送什麼禮物?
當然,不是模板語言,因為它已經有了。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, deferfrom twisted.web.template import tags, flattenStringdef 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 timedef 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 建立模板的方式。另外,我建議從這三個庫之一開始了解。
你是否有另一種深奧的模板方法?請在下面的評論中分享!