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