go開源Hugo站點(diǎn)渲染之模板詞法解析
正文
Deps在準(zhǔn)備好NewPathSpec,NewSpec,NewContentSpec,NewSourceSpec后,調(diào)用onCreate正式創(chuàng)建HugoSites,并在最后一步,加載模板執(zhí)行器。
模板執(zhí)行器只是提前將模板信息轉(zhuǎn)換成了模板執(zhí)行器,如何使用并沒有涉及到。
為了讓我們對模板生命周期有更全面的了解,讓我們以robots.txt為例,來看看是如何通過模板執(zhí)行器生成最終文件的。
了然于胸 - newTemplateExec時序圖
從時序圖中,可以了解到創(chuàng)建執(zhí)行器,主要分兩步。
先創(chuàng)建包含了各種功能函數(shù)的executor。 其中的功能函數(shù)由兩部分組成,一部分來自hugo,像htmlEscape等。 另一部分來自于golang的內(nèi)置函數(shù),如fmt.Sprint等等。 正是因?yàn)橛羞@些功能函數(shù)的支持,才得以讓模板的action塊 - ‘{{}}‘功能如此強(qiáng)大。
執(zhí)行器創(chuàng)建好后,接下來就要創(chuàng)建模板的handler了。 處理器提供了模板加載、查詢等相關(guān)的服務(wù),以方便使用。 因?yàn)椴樵兎?wù)依賴于加載服務(wù),所以在處理器實(shí)例后,緊接著就是加載模板了。 而模板又分兩部分,一部分是由hugo提供的默認(rèn)模板,像robot.txt等。 另一部分就是由用戶所提供的layouts文件,有來于主題的,也有來于用戶自定義的layout。
加載的是磁盤文件,得到的是解析過后的模板實(shí)例。
templ, err := prototype.New(info.name).Parse(info.template)
源碼里用的是prototype,而不是直接用的html。 這是因?yàn)槲覀兊哪0逵袃煞N后綴,一種是txt,另一種是html,需要找到相應(yīng)的原型來對模板進(jìn)行解析。
不管是什么模板,都是文本,HTML也不例外,也是文本。 HTML模板的源碼也應(yīng)證了這一點(diǎn) - 直接調(diào)用文本模板的方法。 那這種關(guān)系是如何用代碼實(shí)現(xiàn)的呢?
拿到模板字節(jié)信息后,用詞法分析器對模板字節(jié)流進(jìn)行解析,得到分析好的詞義結(jié)構(gòu)。 對于HTML模板而言,為了安全,需要對詞義結(jié)構(gòu)進(jìn)行檢查和必要地修改。 因?yàn)槲覀兛梢詮牟煌?,獲得不同的主題,這些主題中又包含了很多模板,并且主題中可以嵌套主題,為了保證安全,避免執(zhí)行惡意代碼。 最后就是執(zhí)行解析好的模板。
為了方便理解,我們來舉個例子 - robot.txt模板使用流程:
- 查找:通過名字查找,調(diào)用templateExec中的handler查詢方法LookupLayout進(jìn)行查詢。
- 執(zhí)行:準(zhǔn)備執(zhí)行模板所需要的信息,調(diào)用templateExec中的executor執(zhí)行方法ExecuteWithContext開始執(zhí)行。 這里的執(zhí)行方法實(shí)際上也是由text template提供的,前面咱們也提到了,不管是什么類型的模板,都是以text為基礎(chǔ)的。
知道了工作流程后,讓我們從源碼層面,更深入的對Template進(jìn)行理解。
我們先來看第一步: 模板解析。
詞法解析 - parse
創(chuàng)建Deps的最后一步是loadResources,其中主要指的是Template資源。 在創(chuàng)建templateExec實(shí)例的過程中,就需要加載hugo默認(rèn)和用戶創(chuàng)建的模板。 加載模板后,獲取了模板的字節(jié)信息,要想為我們所有,首先要讀懂這些字節(jié),這時,我們就用到了解析Parse,而且是由text模板提供的。 Parse為什么可以讀懂這些字符信息呢,她依靠的是內(nèi)部了詞法分析器lex - lexer,分析器需要對action block的語義有充分的理解。 讀懂后轉(zhuǎn)換為方便后續(xù)操作的數(shù)據(jù)結(jié)構(gòu)tree,在hugo中實(shí)際載體是listNode類型。
我們拿一段模板舉個例子:
從上例中,我們可以看到,左上方是輸入的信息。 包含一篇博客 - post.md,和一個模板 - single.html。 通過轉(zhuǎn)換會得到最右邊的輸出網(wǎng)頁內(nèi)容。 其中,包含在模板中第一行的信息,剩下的是由博客提供的信息,其中的特殊字符,還被進(jìn)行了轉(zhuǎn)義。
在左下方第一步中,創(chuàng)建templateExec過程中,讀取到了模板single.html。 通過解析,利用詞法分析器,會得到如下狀態(tài):
[“<p><!-- HT…”, “{{”, “ “, ”.Content”, ” “, ”}}”, EOF]
為了理解其中的工作原理,讓我們在下一章節(jié)中一起來看一下action block的詞法分析器是如何工作的。
以上就是go開源Hugo站點(diǎn)渲染之模板詞法解析的詳細(xì)內(nèi)容,更多關(guān)于Hugo站點(diǎn)渲染模板詞法的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Go語言基礎(chǔ)學(xué)習(xí)之map的示例詳解
哈希表是常見的數(shù)據(jù)結(jié)構(gòu),有的語言會將哈希稱作字典或者映射,在Go中,哈希就是常見的數(shù)據(jù)類型map,本文就來聊聊Golang中map的相關(guān)知識吧2023-04-04golang 并發(fā)安全Map以及分段鎖的實(shí)現(xiàn)方法
這篇文章主要介紹了golang 并發(fā)安全Map以及分段鎖的實(shí)現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-03-03用GO實(shí)現(xiàn)IP門禁優(yōu)化網(wǎng)絡(luò)流量管理
這篇文章主要為大家介紹了用GO實(shí)現(xiàn)IP門禁優(yōu)化網(wǎng)絡(luò)流量管理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12