Hugo 範本與短代碼

最後更新: 2025-10-30 09:45:02 +0800 +0800
tags: Hugo | Go
原文以英文撰寫。您正在閱讀AI翻譯版本。

Hugo 範本將 Go 的範本語言與 Hugo 函式和頁面物件結合。短代碼使用相同的語言, 但內容作者會從 Markdown 呼叫它們,而 Hugo 建構.Content。

遵循 Go 範本的內容脈絡與作用域 #

範本動作會出現在{{與}}之間。管線會將每個命令的結果傳遞給下一個命令的最後一個引數:

go-html-template
{{ .Title | strings.TrimSpace | htmlEscape }}

點號(.)代表目前的內容脈絡。with、range和範本呼叫可以重新繫結它,因此在進入 較窄的作用域前,先擷取外層物件:

go-html-template
{{ $page := . }}
{{ range .Pages }}
  <a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
  <span>{{ $page.Site.Title }}</span>
{{ end }}

變數以$開頭,並在其宣告所在的作用域中保持可見。特殊的根變數$最初指向傳遞給範本 的內容脈絡,但使用明確命名的變數可以讓巢狀程式碼更容易檢閱。

Go 範本函式會回傳可由管線轉換的值。有些函式也會將錯誤作為最後一個結果回傳;非 nil 錯誤會停止範本執行。對選用值使用with;如果缺少值違反內容契約,請使用errorf, 而不是靜默輸出不完整的標記。

保留內容脈絡相關的逸出 #

HTML 版面配置透過 Go 的html/template執行。系統會依據值出現在文字、屬性、URL、CSS 或 JavaScript 中,對值進行相應的逸出:

go-html-template
<a href="{{ .Params.target }}">{{ .Params.label }}</a>

safeHTML、safeCSS、safeJS和safeURL等函式會將值標記為在某一內容脈絡中可信。 它們不會清理不受信任的輸入。只將這些函式套用於由網站產生或驗證的內容,因為使用錯誤的 safe 類型可能建立跨網站指令碼攻擊路徑。

Hugo 類似template.HTML的安全值也會跨越 partial 邊界。因此,partial 應說明它預期的 是純文字、URL、頁面物件,還是受信任的標記。

將明確資料傳遞給 partial #

layouts/_partials/下的 partial 會轉譯可重複使用的範本片段。呼叫端選擇其點號內容脈絡:

go-html-template
{{ partial "card.html" (dict
  "page" .
  "compact" true
) }}

在card.html中可以使用.page和.compact,但原始頁面不會被隱式還原。明確的字典可以 防止 partial 依賴呼叫位置當時碰巧啟用的點號內容脈絡。

partialCached會在建置期間快取 partial 的結果:

go-html-template
{{ partialCached "menu.html" . .Language.Lang .Section }}

快取變體必須包含所有可能改變輸出的輸入。沒有變體鍵時,頁面專屬內容可能會在不相關的 頁面上重複使用。

定位短代碼範本與資源 #

在目前的 Hugo 版本中,專案短代碼範本位於layouts/_shortcodes/下;模組或佈景主題可以 提供優先順序較低的定義。子目錄是短代碼名稱的一部分。呼叫docs/note時,會解析到如下範本:

text
layouts/_shortcodes/docs/note.html

呼叫應放在內容頁面中,該頁面可以是一般檔案,也可以是 bundle 的index.md。資源不應 放在 layout 目錄中。leaf bundle 使用的短代碼可以透過.Page.Resources.Get解析同層 資源,而全站資源來自全域資源管線。

短代碼接收的是短代碼內容脈絡,而不是將周圍頁面作為點號內容脈絡。常見成員包括.Page、 .Params、.Get、.Inner、.InnerDeindent、.Ordinal和.Parent。具名引數和 位置引數不應含糊地混用:

go-html-template
{{ $src := .Get "src" }}
{{ with .Page.Resources.Get $src }}
  <img src="{{ .RelPermalink }}" alt="{{ $.Get "alt" }}">
{{ else }}
  {{ errorf "shortcode image %q not found in %s" $src $.Page.Path }}
{{ end }}

選擇 Markdown 邊界 #

Hugo 提供兩種分隔符形式:

  • {{< note >}}插入短代碼範本輸出,但不會將該輸出傳給 Markdown 轉譯器。
  • {{% note %}}會將短代碼範本輸出傳給 Markdown 轉譯。

當短代碼產生 Markdown 時,百分比形式較適合。當範本負責最終 HTML 時,角括號形式較適合。 Markdown 形式中的縮排仍然重要,因為四個空格可能會將產生的內容轉為程式碼區塊。 Goldmark 的 unsafe-HTML 設定也會影響進入 Markdown 路徑的原始 HTML。

對於成對短代碼,Hugo 解決巢狀短代碼呼叫後,其內部內容會位於.Inner中。短代碼範本 決定要直接轉譯該值,或透過.Page.RenderString傳遞它;不要再次轉譯已經轉譯過的值。

安全輸出字面分隔符 #

看起來像短代碼的 Markdown 文字無法透過 Markdown 程式碼圍欄得到保護,因為短代碼展開會在 Markdown 轉譯器處理圍欄之前發生。Hugo 的註解逸出可以輸出字面範例,而不會嘗試查找:

text
{{< note >}}
{{% note %}}

如果轉譯後的頁面只需要顯示分隔符,也可以使用 HTML 實體。當讀者需要從轉譯結果複製 字面短代碼語法時,請使用註解逸出。

診斷查找與執行失敗 #

未知短代碼通常會回報內容檔案和短代碼名稱。依序檢查:

  1. 呼叫位置使用的名稱與大小寫。
  2. _shortcodes目錄,以及名稱中的任何子目錄。
  3. 目前啟用的模組掛載和佈景主題優先順序。
  4. 專案版本是否要求使用目前的 layout 命名空間。
  5. 查找成功後範本執行是否失敗,原因可能是缺少引數或資源。

對於可繼續執行的可操作診斷,使用warnf;對於必須使建置失敗的破壞性不變條件, 使用errorf。範本提供網站結構,partial 重複使用結構,而短代碼則將作者控制的內容與 刻意限制範圍的範本 API 連接起來。

評論

在 GitHub 上閱讀或評論(發表評論需要登入)