HUGO
Menu
GitHub 87548 stars Mastodon

Hugo 內容適配器

創建內容適配器以在構建站點時動態添加內容。
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" "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

向站點添加頁面資源。

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/page.html
{{ with .Resources.Get "cover.jpg" }}
  <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
{{ end }}

Site

返回將添加頁面的 Site

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

請注意,從內容適配器調用時返回的 Site 尚未完全構建;如果你嘗試調用依賴於頁面的方法,例如 .Site.Pages,你會收到錯誤提示"this method cannot be called before the site is fully initialized"。

Store

返回一個持久的"scratch pad"來存儲和操作數據。這的主要用例是在 EnableAllLanguages 設置時在多次執行之間傳輸值。參見 示例

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

EnableAllLanguages

默認情況下,Hugo 只為 sites matrix 中第一個匹配的站點執行內容適配器一次。使用此方法將執行擴展到所有語言,同時保持當前角色和版本。

對於更細粒度的控制,在 front matter 或內容掛載中定義 sites.matrix

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

New in v0.153.0

頁面映射

在傳遞給 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 }}

多語言站點

使用多語言站點,你可以:

  1. 使用上面的 EnableAllLanguages 方法為所有語言創建一個內容適配器。
  2. 為每種語言創建獨特的內容適配器。參見下面的示例。

按文件名翻譯

使用此站點配置:

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 標志。


Last updated: January 1, 0001
Improve this page