Content adapters
概覽
內容掛載器是一種範本,用於在建置網站時動態建立頁面。例如,可以使用內容掛載器從遠端資料來源(如 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" "《鐘樓怪人》是由維克多·雨果所撰寫。"
}}
{{ $page := dict
"content" $content
"kind" "page"
"path" "the-hunchback-of-notre-dame"
"title" "鐘樓怪人"
}}
{{ .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 }}
Store
返回一個持久化的「暫存區」以儲存及操作資料。主要用途是在設定 EnableAllLanguages
時,在不同執行之間傳遞值。參見範例。
{{ .Store.Set "key" "value" }}
{{ .Store.Get "key" }}
EnableAllLanguages
預設情況下,Hugo 僅執行由 _content.gotmpl
文件所定義語言的內容掛載器。使用此方法可啟用內容掛載器在所有語言中運作。
{{ .EnableAllLanguages }}
{{ $content := dict
"mediaType" "text/markdown"
"value" "《鐘樓怪人》是由維克多·雨果所撰寫。"
}}
{{ $page := dict
"content" $content
"kind" "page"
"path" "the-hunchback-of-notre-dame"
"title" "鐘樓怪人"
}}
{{ .AddPage $page }}
頁面映射
您可以在傳遞至 AddPage
方法的映射中設定任何[前置參數欄位],但不包括 markup
。而是指定 content.mediaType
,如下所述。
以下表格描述了最常傳遞至 AddPage
方法的欄位。
鍵值 | 描述 | 必填 |
---|---|---|
content.mediaType |
內容媒體類型。預設為 text/markdown 。參見內容格式範例。 |
|
content.value |
內容值,為字串格式。 | |
dates.date |
頁面建立日期,為 time.Time 值。 |
|
dates.expiryDate |
頁面到期日期,為 time.Time 值。 |
|
dates.lastmod |
頁面最後修改日期,為 time.Time 值。 |
|
dates.publishDate |
頁面發佈日期,為 time.Time 值。 |
|
kind |
頁面的[類型]。預設為 page 。 |
|
params |
頁面參數的映射。 | |
path |
頁面的邏輯路徑,相對於內容掛載器。請勿包含開頭斜線或副檔名。 | ✓ |
title |
頁面標題。 |
資源映射
使用以下欄位構建傳遞至 AddResource
方法的映射。
鍵值 | 描述 | 必填 |
---|---|---|
content.mediaType |
內容媒體類型 | ✓ |
content.value |
內容值,為字串或資源格式。 | ✓ |
name |
資源名稱。 | |
params |
資源參數的映射。 | |
path |
資源的邏輯路徑,相對於內容掛載器。請勿包含開頭斜線。 | ✓ |
title |
資源標題。 |
範例
從遠端數據建立頁面,每個頁面代表一本書的評論。
第一步
建立內容結構。
content/
└── books/
├── _content.gotmpl <-- 內容適配器
└── _index.md
第二步
檢查遠端數據以確定如何將鍵值對映射到 Front Matter 欄位。
資料連結:https://gohugo.io/shared/examples/data/books.json
第三步
建立內容適配器。
{{/* 獲取遠端數據。 */}}
{{ $data := dict }}
{{ $url := "https://gohugo.io/shared/examples/data/books.json" }}
{{ with resources.GetRemote $url }}
{{ with .Err }}
{{ errorf "無法取得遠端資源 %s: %s" $url . }}
{{ else }}
{{ $data = . | transform.Unmarshal }}
{{ end }}
{{ else }}
{{ errorf "無法取得遠端資源 %s" $url }}
{{ 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 resources.GetRemote $url }}
{{ with .Err }}
{{ errorf "無法取得遠端資源 %s: %s" $url . }}
{{ else }}
{{ $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 }}
{{ end }}
{{ else }}
{{ errorf "無法取得遠端資源 %s" $url }}
{{ end }}
{{ end }}
{{ end }}
第四步
建立單一模板來渲染每本書的評論。
{{ 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
參數。