Hugo 短代碼模板
介紹
Hugo 為許多常見任務提供 嵌入式短代碼,但您可能需要為更具體的需求創建自己的短代碼。您可能開發的一些自定義短代碼示例包括:
- 音頻播放器
- 視頻播放器
- 圖像畫廊
- 圖表
- 地圖
- 表格
- 以及許多其他自定義元素
目錄結構
在 layouts/_shortcodes 目錄中創建 短代碼 模板,可以在其根目錄或組織到子目錄中。
layouts/
└── _shortcodes/
├── diagrams/
│ ├── kroki.html
│ └── plotly.html
├── media/
│ ├── audio.html
│ ├── gallery.html
│ └── video.html
├── capture.html
├── column.html
├── include.html
└── row.html在子目錄中調用短代碼時,指定其相對於 _shortcode 目錄的路徑,不包括文件擴展名。
{{< media/audio path=/audio/podcast/episode-42.mp3 >}}查找順序
Hugo 根據短代碼名稱、當前輸出格式和當前語言選擇 短代碼 模板。下面的示例按特異性降序排序。最不具體的路徑在列表底部。
| 短代碼名稱 | 輸出格式 | 語言 | 模板路徑 |
|---|---|---|---|
| foo | html | en | layouts/_shortcodes/foo.en.html |
| foo | html | en | layouts/_shortcodes/foo.html.html |
| foo | html | en | layouts/_shortcodes/foo.html |
| foo | html | en | layouts/_shortcodes/foo.html.en.html |
| 短代碼名稱 | 輸出格式 | 語言 | 模板路徑 |
|---|---|---|---|
| foo | rss | en | layouts/_shortcodes/foo.en.rss.xml |
| foo | rss | en | layouts/_shortcodes/foo.rss.xml |
| foo | rss | en | layouts/_shortcodes/foo.en.xml |
| foo | rss | en | layouts/_shortcodes/foo.xml |
方法
在您的 短代碼 模板中使用這些方法。請參閱每個方法的文檔以獲取詳細信息和示例。
- Get
- 返回給定參數的值。
- Inner
- 返回 shortcode 開始和結束標簽之間的內容,適用於 shortcode 調用包含結束標簽的情況。
- InnerDeindent
- 返回 shortcode 開始和結束標簽之間的內容,並移除縮進,適用於 shortcode 調用包含結束標簽的情況。
- IsNamedParams
- 報告 shortcode 調用是否使用命名參數。
- Name
- 返回 shortcode 文件名,不包括文件擴展名。
- Ordinal
- 返回 shortcode 相對於其父級的從零開始的序號。
- Page
- 返回調用 shortcode 的頁面對象。
- Params
- 返回 shortcode 參數的集合。
- Parent
- 在嵌套 shortcode 中返回父 shortcode 上下文。
- Position
- 返回調用 shortcode 的文件名和位置。
- Ref
- 返回具有給定路徑、語言和輸出格式的頁面的絕對 URL。
- RelRef
- 返回具有給定路徑、語言和輸出格式的頁面的相對 URL。
- Scratch
- 返回一個"暫存板"來存儲和操作數據,作用域為當前 shortcode。
- Site
- 返回站點對象。
- Store
- 返回一個"暫存板"來存儲和操作數據,作用域為當前 shortcode。
示例
這些示例的復雜度從簡單到中等高級,有些為清晰起見進行了簡化。
插入年份
創建短代碼以插入當前年份:
{{- now.Format "2006" -}}然後在標記內調用短代碼:
這是 {{< year >}},看看我們走了多遠。此短代碼可以內聯使用或作為塊單獨使用。如果短代碼可能內聯使用,請使用帶連字符的 模板動作 分隔符刪除周圍的 空白。
插入圖像
此示例假設以下內容結構,其中 content/example/index.md 是包含一個或多個 頁面資源 的 頁面捆綁。
content/
├── example/
│ ├── a.jpg
│ └── index.md
└── _index.md創建短代碼以捕獲圖像作為頁面資源,將其調整為給定寬度,轉換為 WebP 格式,並添加 alt 屬性:
{{- with .Page.Resources.Get (.Get "path") }}
{{- with .Process (printf "resize %dx wepb" ($.Get "width")) -}}
<img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="{{ $.Get "alt" }}">
{{- end }}
{{- end -}}然後在標記內調用短代碼:
{{< image path=a.jpg width=300 alt="一只白色的小貓" >}}上面的示例使用了:
確保您徹底理解上下文的概念。新手用戶最常見的模板錯誤與上下文有關。
在 模板入門介紹 中閱讀有關上下文的更多信息。
插入圖像並處理錯誤
前面的示例雖然功能齊全,但如果圖像缺失則靜默失敗,並且在缺少必需參數時不會優雅地退出。我們將添加錯誤處理來解決這些問題:
{{- with .Get "path" }}
{{- with $r := $.Page.Resources.Get ($.Get "path") }}
{{- with $.Get "width" }}
{{- with $r.Process (printf "resize %dx wepb" ($.Get "width" )) }}
{{- $alt := or ($.Get "alt") "" -}}
<img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="{{ $alt }}">
{{- end }}
{{- else }}
{{- errorf "短代碼 %q 需要 'width' 參數:見 %s" $.Name $.Position }}
{{- end }}
{{- else }}
{{- warnf "短代碼 %q 無法找到 %s:見 %s" $.Name ($.Get "path") $.Position }}
{{- end }}
{{- else }}
{{- errorf "短代碼 %q 需要 'path' 參數:見 %s" .Name .Position }}
{{- end -}}如果作者疏忽了提供 path 或 width 參數,此模板將拋出錯誤並優雅地失敗構建,如果在指定路徑找不到圖像,則發出警告。如果作者未提供 alt 參數,則 alt 屬性設置為空字符串。
Name 和 Position 方法為錯誤和警告提供有用的上下文。例如,缺少 width 參數會導致短代碼拋出此錯誤:
ERROR 短代碼 "image" 需要 'width' 參數:見 "/home/user/project/content/example/index.md:7:1"位置參數
短代碼參數可以 命名或位置。我們之前使用了命名參數;讓我們探索位置參數。這是我們示例的命名參數版本:
{{< image path=a.jpg width=300 alt="一只白色的小貓" >}}這是使用位置參數調用它的方式:
{{< image a.jpg 300 "一只白色的小貓" >}}使用從零開始的鍵的 Get 方法,我們將在模板中初始化具有描述性名稱的變量:
{{ $path := .Get 0 }}
{{ $width := .Get 1 }}
{{ $alt := .Get 2 }}位置參數適用於經常使用且有一到兩個參數的短代碼。由於您會經常使用它們,參數順序將很容易記住。對於不經常使用的短代碼,或那些有兩個以上參數的短代碼,命名參數提高了可讀性並減少了錯誤機會。
命名和位置參數
您可以創建同時接受命名和位置參數的短代碼,但不能同時使用。使用 IsNamedParams 方法確定短代碼調用是使用命名還是位置參數:
{{ $path := cond (.IsNamedParams) (.Get "path") (.Get 0) }}
{{ $width := cond (.IsNamedParams) (.Get "width") (.Get 1) }}
{{ $alt := cond (.IsNamedParams) (.Get "alt") (.Get 2) }}此示例使用 cond 作為 compare.Conditional 函數的別名,如果 IsNamedParams 返回 true 則按名稱獲取參數,否則按位置獲取參數。
參數集合
使用 Params 方法將參數作為集合訪問。
使用命名參數時,Params 方法返回映射:
{{< image path=a.jpg width=300 alt="一只白色的小貓" >}}{{ .Params.path }} → a.jpg
{{ .Params.width }} → 300
{{ .Params.alt }} → 一只白色的小貓使用位置參數時,Params 方法返回切片:
{{< image a.jpg 300 "一只白色的小貓" >}}{{ index .Params 0 }} → a.jpg
{{ index .Params 1 }} → 300
{{ index .Params 2 }} → 一只白色的小貓將 Params 方法與 collections.IsSet 函數結合使用以確定是否設置了參數,即使其值是假值。
內部內容
使用 Inner 方法提取短代碼標簽內包含的內容。此示例演示如何將內容和標題傳遞給短代碼。然後短代碼生成包含 h2 元素(顯示標題)和所提供內容的 div 元素。
{{< contrived title="一個虛構的示例" >}}
這是一個 **粗體** 詞,這是一個 _強調_ 詞。
{{< /contrived >}}<div class="contrived">
<h2>{{ .Get "title" }}</h2>
{{ .Inner | .Page.RenderString }}
</div>前面的示例使用 標准表示法 調用短代碼,需要我們使用 RenderString 方法處理內部內容以將 Markdown 轉換為 HTML。當使用 Markdown 表示法 調用短代碼時,不需要此轉換。
嵌套
Parent 方法在短代碼在父短代碼上下文中調用時提供對父短代碼上下文的訪問。這提供了一個繼承模型。
以下示例是虛構的但演示了概念。假設您有一個 gallery 短代碼,期望一個命名 class 參數:
<div class="{{ .Get "class" }}">
{{ .Inner }}
</div>您還有一個具有單個命名 src 參數的 img 短代碼,您希望在 gallery 和其他短代碼內調用它,以便父級定義每個 img 的上下文:
{{ $src := .Get "src" }}
{{ with .Parent }}
<img src="{{ $src }}" class="{{ .Get "class" }}-image">
{{ else }}
<img src="{{ $src }}">
{{ end }}然後您可以在內容中調用短代碼,如下所示:
{{< gallery class="content-gallery" >}}
{{< img src="/images/one.jpg" >}}
{{< img src="/images/two.jpg" >}}
{{< /gallery >}}
{{< img src="/images/three.jpg" >}}這將輸出以下 HTML。請注意前兩個 img 短代碼如何繼承父 gallery 調用設置的 class 值 content-gallery,而第三個 img 僅使用 src:
<div class="content-gallery">
<img src="/images/one.jpg" class="content-gallery-image">
<img src="/images/two.jpg" class="content-gallery-image">
</div>
<img src="/images/three.jpg">其他示例
作為指導,請考慮檢查 Hugo 的嵌入式短代碼。源代碼可在 GitHub 上獲取,可以提供有用的模型。
檢測
HasShortcode 方法允許您檢查頁面上是否調用了特定短代碼。例如,考慮自定義音頻短代碼:
{{< audio src=/audio/test.mp3 >}}您可以在基礎模板中使用 HasShortcode 方法,如果頁面上使用了音頻短代碼,則有條件地加載 CSS:
<head>
...
{{ if .HasShortcode "audio" }}
<link rel="stylesheet" src="/css/audio.css">
{{ end }}
...
</head>