Hugo 內容適配器
概述
內容適配器是一種模板,在構建站點時動態創建頁面。例如,使用內容適配器從遠程數據源(如 JSON、TOML、YAML 或 XML)創建頁面。
與駐留在 layouts 目錄中的模板不同,內容適配器駐留在 content 目錄中,每種語言每個目錄不超過一個。當內容適配器創建頁面時,頁面的 邏輯路徑 將相對於內容適配器。
content/
├── articles/
│ ├── _index.md
│ ├── article-1.md
│ └── article-2.md
├── books/
│ ├── _content.gotmpl <-- 內容適配器
│ └── _index.md
└── films/
├── _content.gotmpl <-- 內容適配器
└── _index.md每個內容適配器命名為 _content.gotmpl,使用與 layouts 目錄中模板相同的 語法。你可以在內容適配器中使用任何 模板函數,以及下面描述的方法。
方法
在內容適配器中使用這些方法。
AddPage
向站點添加頁面。
{{ $content := dict
"mediaType" "text/markdown"
"value" "The _Hunchback of Notre Dame_ was written by Victor Hugo."
}}
{{ $page := dict
"content" $content
"kind" "page"
"path" "the-hunchback-of-notre-dame"
"title" "The Hunchback of Notre Dame"
}}
{{ .AddPage $page }}AddResource
向站點添加頁面資源。
{{ with resources.Get "images/a.jpg" }}
{{ $content := dict
"mediaType" .MediaType.Type
"value" .
}}
{{ $resource := dict
"content" $content
"path" "the-hunchback-of-notre-dame/cover.jpg"
}}
{{ $.AddResource $resource }}
{{ end }}然後使用類似以下內容檢索新頁面資源:
{{ with .Resources.Get "cover.jpg" }}
<img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
{{ end }}Site
返回將添加頁面的 Site。
{{ .Site.Title }}請注意,從內容適配器調用時返回的 Site 尚未完全構建;如果你嘗試調用依賴於頁面的方法,例如 .Site.Pages,你會收到錯誤提示"this method cannot be called before the site is fully initialized"。
Store
返回一個持久的"scratch pad"來存儲和操作數據。這的主要用例是在 EnableAllLanguages 設置時在多次執行之間傳輸值。參見 示例。
{{ .Store.Set "key" "value" }}
{{ .Store.Get "key" }}EnableAllLanguages
默認情況下,Hugo 只為 sites matrix 中第一個匹配的站點執行內容適配器一次。使用此方法將執行擴展到所有語言,同時保持當前角色和版本。
對於更細粒度的控制,在 front matter 或內容掛載中定義 sites.matrix。
{{ .EnableAllLanguages }}
{{ $content := dict
"mediaType" "text/markdown"
"value" "The _Hunchback of Notre Dame_ was written by Victor Hugo."
}}
{{ $page := dict
"content" $content
"kind" "page"
"path" "the-hunchback-of-notre-dame"
"title" "The Hunchback of Notre Dame"
}}
{{ .AddPage $page }}EnableAllDimensions
默認情況下,Hugo 只為 sites matrix 中第一個匹配的站點執行內容適配器一次。使用此方法將執行擴展到語言、角色和版本的每種可能組合。
對於更細粒度的控制,在 front matter 或內容掛載中定義 sites.matrix。
頁面映射
在傳遞給 AddPage 方法的映射中設置任何 front matter 字段,不包括 markup。代替設置 markup 字段,如下所述指定 content.mediaType。
此表描述了最常傳遞給 AddPage 方法的字段。
| Key | 描述 | 必需 |
|---|---|---|
content.mediaType |
內容 media type。默認是 text/markdown。參見 內容格式 示例。 |
|
content.value |
內容值為字符串。 | |
dates.date |
頁面創建日期,為 time.Time 值。 |
|
dates.expiryDate |
頁面失效日期,為 time.Time 值。 |
|
dates.lastmod |
頁面最後修改日期,為 time.Time 值。 |
|
dates.publishDate |
頁面發布日期,為 time.Time 值。 |
|
params |
頁面參數映射。 | |
path |
頁面相對於內容適配器的 邏輯路徑。不要包含前導斜槓或文件擴展名。 | ✔️ |
title |
頁面標題。 |
雖然 path 是唯一必需字段,但我們也建議設置 title。
設置 path 時,Hugo 將給定字符串轉換為邏輯路徑。例如,將 path 設置為 A B C 會產生邏輯路徑 /section/a-b-c。
資源映射
使用以下字段構建傳遞給 AddResource 方法的映射。
| Key | 描述 | 必需 |
|---|---|---|
content.mediaType |
內容 media type。 | ✔️ |
content.value |
內容值為字符串或資源。 | ✔️ |
name |
資源名稱。 | |
params |
資源參數映射。 | |
path |
資源相對於內容適配器的 邏輯路徑。不要包含前導斜槓。 | ✔️ |
title |
資源標題。 |
當 content.value 是字符串時,Hugo 生成一個相對於頁面的發布路徑的新資源。但是,如果 content.value 已經是資源,Hugo 直接使用其值並將其相對於站點根目錄發布。後一種方法更高效。
設置 path 時,Hugo 將給定字符串轉換為邏輯路徑。例如,將 path 設置為 A B C/cover.jpg 會產生邏輯路徑 /section/a-b-c/cover.jpg。
示例
從遠程數據創建頁面,每個頁面代表一篇書評。
- Step 1
- 創建內容結構。
content/ └── books/ ├── _content.gotmpl <-- 內容適配器 └── _index.md - Step 2
- 檢查遠程數據以確定如何將鍵值對映射到 front matter 字段。
https://www.hugodoc.com/shared/examples/data/books.json - Step 3
- 創建內容適配器。
content/books/_content.gotmpl
{{/* 獲取遠程數據。*/}} {{ $data := dict }} {{ $url := "https://www.hugodoc.com/shared/examples/data/books.json" }} {{ with try (resources.GetRemote $url) }} {{ with .Err }} {{ errorf "Unable to get remote resource %s: %s" $url . }} {{ else with .Value }} {{ $data = . | transform.Unmarshal }} {{ else }} {{ errorf "Unable to get remote resource %s" $url }} {{ end }} {{ end }} {{/* 添加頁面和頁面資源。*/}} {{ range $data }} {{/* 添加頁面。*/}} {{ $content := dict "mediaType" "text/markdown" "value" .summary }} {{ $dates := dict "date" (time.AsTime .date) }} {{ $params := dict "author" .author "isbn" .isbn "rating" .rating "tags" .tags }} {{ $page := dict "content" $content "dates" $dates "kind" "page" "params" $params "path" .title "title" .title }} {{ $.AddPage $page }} {{/* 添加頁面資源。*/}} {{ $item := . }} {{ with $url := $item.cover }} {{ with try (resources.GetRemote $url) }} {{ with .Err }} {{ errorf "Unable to get remote resource %s: %s" $url . }} {{ else with .Value }} {{ $content := dict "mediaType" .MediaType.Type "value" .Content }} {{ $params := dict "alt" $item.title }} {{ $resource := dict "content" $content "params" $params "path" (printf "%s/cover.%s" $item.title .MediaType.SubType) }} {{ $.AddResource $resource }} {{ else }} {{ errorf "Unable to get remote resource %s" $url }} {{ end }} {{ end }} {{ end }} {{ end }} - Step 4
- 創建 page 模板來渲染每篇書評。
layouts/books/page.html
{{ define "main" }} <h1>{{ .Title }}</h1> {{ with .Resources.GetMatch "cover.*" }} <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="{{ .Params.alt }}"> {{ end }} <p>作者:{{ .Params.author }}</p> <p> ISBN: {{ .Params.isbn }}<br> 評分:{{ .Params.rating }}<br> 評論日期:{{ .Date | time.Format ":date_long" }} </p> {{ with .GetTerms "tags" }} <p>標簽:</p> <ul> {{ range . }} <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li> {{ end }} </ul> {{ end }} {{ .Content }} {{ end }}
多語言站點
使用多語言站點,你可以:
- 使用上面的
EnableAllLanguages方法為所有語言創建一個內容適配器。 - 為每種語言創建獨特的內容適配器。參見下面的示例。
按文件名翻譯
使用此站點配置:
languages:
de:
weight: 2
en:
weight: 1
[languages]
[languages.de]
weight = 2
[languages.en]
weight = 1
{
"languages": {
"de": {
"weight": 2
},
"en": {
"weight": 1
}
}
}
在內容適配器的文件名中包含語言標識符。
content/
└── books/
├── _content.de.gotmpl
├── _content.en.gotmpl
├── _index.de.md
└── _index.en.md按內容目錄翻譯
使用此站點配置:
languages:
de:
contentDir: content/de
weight: 2
en:
contentDir: content/en
weight: 1
[languages]
[languages.de]
contentDir = 'content/de'
weight = 2
[languages.en]
contentDir = 'content/en'
weight = 1
{
"languages": {
"de": {
"contentDir": "content/de",
"weight": 2
},
"en": {
"contentDir": "content/en",
"weight": 1
}
}
}
在每個目錄中創建單個內容適配器:
content/
├── de/
│ └── books/
│ ├── _content.gotmpl
│ └── _index.md
└── en/
└── books/
├── _content.gotmpl
└── _index.md頁面沖突
當兩個或多個頁面具有相同的發布路徑時會發生沖突。由於並發,已發布頁面的內容是不確定的。考慮以下示例:
content/
└── books/
├── _content.gotmpl <-- 內容適配器
├── _index.md
└── the-hunchback-of-notre-dame.md如果內容適配器也創建 books/the-hunchback-of-notre-dame,則已發布頁面的內容是不確定的。你無法定義處理順序。
要檢測頁面沖突,在構建站點時使用 --printPathWarnings 標志。