CONTENT MANAGEMENT

Content adapters

New in v0.126.0

概覽

內容掛載器是一種範本,用於在建置網站時動態建立頁面。例如,可以使用內容掛載器從遠端資料來源(如 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/books/_content.gotmpl
{{ $content := dict
  "mediaType" "text/markdown"
  "value" "《鐘樓怪人》是由維克多·雨果所撰寫。"
}}
{{ $page := dict
  "content" $content
  "kind" "page"
  "path" "the-hunchback-of-notre-dame"
  "title" "鐘樓怪人"
}}
{{ .AddPage $page }}
AddResource

新增頁面資源至網站。

content/books/_content.gotmpl
{{ 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 }}

接著,您可以使用以下範例取得新的頁面資源:

layouts/_default/single.html
{{ with .Resources.Get "cover.jpg" }}
  <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
{{ end }}
Site

返回將新增頁面的 Site。

content/books/_content.gotmpl
{{ .Site.Title }}
Store

返回一個持久化的「暫存區」以儲存及操作資料。主要用途是在設定 EnableAllLanguages 時,在不同執行之間傳遞值。參見範例。

content/books/_content.gotmpl
{{ .Store.Set "key" "value" }}
{{ .Store.Get "key" }}
EnableAllLanguages

預設情況下,Hugo 僅執行由 _content.gotmpl 文件所定義語言的內容掛載器。使用此方法可啟用內容掛載器在所有語言中運作。

content/books/_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

第三步

建立內容適配器。

content/books/_content.gotmpl
{{/* 獲取遠端數據。 */}}
{{ $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 }}

第四步

建立單一模板來渲染每本書的評論。

layouts/books/single.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 }}

多語系網站

在多語系網站中,您可以:

  1. 使用 EnableAllLanguages 方法為所有語言建立一個內容適配器,詳見上文描述。
  2. 為每種語言建立獨特的內容適配器。請參考以下範例。

依檔名進行翻譯

以下是網站設定範例:

hugo.
     
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

依內容目錄進行翻譯

以下是網站設定範例:

hugo.
     
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 參數。