内容适配器
概述
内容适配器是一个模板,它在构建站点时动态创建页面。例如,可以使用内容适配器从远程数据源(例如 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
。无需设置 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 |
资源标题。 |
示例
从远程数据创建页面,其中每个页面代表一篇书评。
- 步骤 1
- 创建内容结构。
content/
└── books/
├── _content.gotmpl <-- 内容适配器
└── _index.md
- 步骤 2
- 检查远程数据以确定如何将键值对映射到前题字段。
- 步骤 3
- 创建内容适配器。
{{/* 获取远程数据。 */}}
{{ $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 }}
- 步骤 4
- 创建一个单个模板来呈现每篇书评。
{{ 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
标志。