go開源Hugo站點渲染之模板詞法解析

正文

Deps在準備好NewPathSpec,NewSpec,NewContentSpec,NewSourceSpec後,調用onCreate正式創建HugoSites,並在最後一步,加載模板執行器。

模板執行器隻是提前將模板信息轉換成瞭模板執行器,如何使用並沒有涉及到。

為瞭讓我們對模板生命周期有更全面的瞭解,讓我們以robots.txt為例,來看看是如何通過模板執行器生成最終文件的。

瞭然於胸 – newTemplateExec時序圖 

從時序圖中,可以瞭解到創建執行器,主要分兩步。

先創建包含瞭各種功能函數的executor。 其中的功能函數由兩部分組成,一部分來自hugo,像htmlEscape等。 另一部分來自於golang的內置函數,如fmt.Sprint等等。 正是因為有這些功能函數的支持,才得以讓模板的action塊 – ‘{{}}‘功能如此強大。

執行器創建好後,接下來就要創建模板的handler瞭。 處理器提供瞭模板加載、查詢等相關的服務,以方便使用。 因為查詢服務依賴於加載服務,所以在處理器實例後,緊接著就是加載模板瞭。 而模板又分兩部分,一部分是由hugo提供的默認模板,像robot.txt等。 另一部分就是由用戶所提供的layouts文件,有來於主題的,也有來於用戶自定義的layout。

加載的是磁盤文件,得到的是解析過後的模板實例。

templ, err := prototype.New(info.name).Parse(info.template)

源碼裡用的是prototype,而不是直接用的html。 這是因為我們的模板有兩種後綴,一種是txt,另一種是html,需要找到相應的原型來對模板進行解析。

不管是什麼模板,都是文本,HTML也不例外,也是文本。 HTML模板的源碼也應證瞭這一點 – 直接調用文本模板的方法。 那這種關系是如何用代碼實現的呢?

拿到模板字節信息後,用詞法分析器對模板字節流進行解析,得到分析好的詞義結構。 對於HTML模板而言,為瞭安全,需要對詞義結構進行檢查和必要地修改。 因為我們可以從不同渠道,獲得不同的主題,這些主題中又包含瞭很多模板,並且主題中可以嵌套主題,為瞭保證安全,避免執行惡意代碼。 最後就是執行解析好的模板。

為瞭方便理解,我們來舉個例子 – robot.txt模板使用流程:

  • 查找:通過名字查找,調用templateExec中的handler查詢方法LookupLayout進行查詢。
  • 執行:準備執行模板所需要的信息,調用templateExec中的executor執行方法ExecuteWithContext開始執行。 這裡的執行方法實際上也是由text template提供的,前面咱們也提到瞭,不管是什麼類型的模板,都是以text為基礎的。

知道瞭工作流程後,讓我們從源碼層面,更深入的對Template進行理解。

我們先來看第一步: 模板解析。

詞法解析 – parse 

創建Deps的最後一步是loadResources,其中主要指的是Template資源。 在創建templateExec實例的過程中,就需要加載hugo默認和用戶創建的模板。 加載模板後,獲取瞭模板的字節信息,要想為我們所有,首先要讀懂這些字節,這時,我們就用到瞭解析Parse,而且是由text模板提供的。 Parse為什麼可以讀懂這些字符信息呢,她依靠的是內部瞭詞法分析器lex – lexer,分析器需要對action block的語義有充分的理解。 讀懂後轉換為方便後續操作的數據結構tree,在hugo中實際載體是listNode類型。

我們拿一段模板舉個例子:

從上例中,我們可以看到,左上方是輸入的信息。 包含一篇博客 – post.md,和一個模板 – single.html。 通過轉換會得到最右邊的輸出網頁內容。 其中,包含在模板中第一行的信息,剩下的是由博客提供的信息,其中的特殊字符,還被進行瞭轉義。

在左下方第一步中,創建templateExec過程中,讀取到瞭模板single.html。 通過解析,利用詞法分析器,會得到如下狀態:

[“<p><!-- HT…”, “{{”, “ “, ”.Content”, ” “, ”}}”, EOF]

為瞭理解其中的工作原理,讓我們在下一章節中一起來看一下action block的詞法分析器是如何工作的。

以上就是go開源Hugo站點渲染之模板詞法解析的詳細內容,更多關於Hugo站點渲染模板詞法的資料請關註WalkonNet其它相關文章!

推薦閱讀: