mirror of
https://github.com/gohugoio/hugoDocs.git
synced 2025-09-10 16:56:29 -04:00
Document content adapters
This commit is contained in:
parent
653069a0d0
commit
5ee96971ad
@ -114,6 +114,7 @@
|
|||||||
"# ----------------------------------------------------------------------",
|
"# ----------------------------------------------------------------------",
|
||||||
"# cspell: ignore names",
|
"# cspell: ignore names",
|
||||||
"# ----------------------------------------------------------------------",
|
"# ----------------------------------------------------------------------",
|
||||||
|
"Atishay",
|
||||||
"Eliott",
|
"Eliott",
|
||||||
"Furet",
|
"Furet",
|
||||||
"Gregor",
|
"Gregor",
|
||||||
@ -132,6 +133,7 @@
|
|||||||
"cifs",
|
"cifs",
|
||||||
"corejs",
|
"corejs",
|
||||||
"disqus",
|
"disqus",
|
||||||
|
"docutils",
|
||||||
"dpkg",
|
"dpkg",
|
||||||
"doas",
|
"doas",
|
||||||
"eopkg",
|
"eopkg",
|
||||||
@ -161,6 +163,7 @@
|
|||||||
"rsmith",
|
"rsmith",
|
||||||
"tdewolff",
|
"tdewolff",
|
||||||
"tjones",
|
"tjones",
|
||||||
|
"wcag",
|
||||||
"xfeff"
|
"xfeff"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 42 KiB |
339
content/en/content-management/content-adapters.md
Normal file
339
content/en/content-management/content-adapters.md
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
---
|
||||||
|
title: Content adapters
|
||||||
|
description: Create content adapters to dynamically add content when building your site.
|
||||||
|
categories: [content management]
|
||||||
|
keywords: []
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
parent: content-management
|
||||||
|
weight: 280
|
||||||
|
weight: 280
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
{{< new-in 0.126.0 >}}
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
A content adapter is a template that dynamically creates pages when building a site. For example, use a content adapter to create pages from a remote data source such as JSON, TOML, YAML, or XML.
|
||||||
|
|
||||||
|
Unlike templates that reside in the layouts directory, content adapters reside in the content directory, no more than one per directory per language. When a content adapter creates a page, the page's [logical path] will be relative to the content adapter.
|
||||||
|
|
||||||
|
```text
|
||||||
|
content/
|
||||||
|
├── articles/
|
||||||
|
│ ├── _index.md
|
||||||
|
│ ├── article-1.md
|
||||||
|
│ └── article-2.md
|
||||||
|
├── books/
|
||||||
|
│ ├── _content.gotmpl <-- content adapter
|
||||||
|
│ └── _index.md
|
||||||
|
└── films/
|
||||||
|
├── _content.gotmpl <-- content adapter
|
||||||
|
└── _index.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Each content adapter is named _content.gotmpl and uses the same [syntax] as templates in the layouts directory. You can use any of the [template functions] within a content adapter, as well as the methods described below.
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
|
||||||
|
Use these methods within a content adapter.
|
||||||
|
|
||||||
|
###### AddPage
|
||||||
|
|
||||||
|
Adds a page to the site.
|
||||||
|
|
||||||
|
{{< code file=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 }}
|
||||||
|
{{< /code >}}
|
||||||
|
|
||||||
|
###### AddResource
|
||||||
|
|
||||||
|
Adds a page resource to the site.
|
||||||
|
|
||||||
|
{{< code file=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 }}
|
||||||
|
{{< /code >}}
|
||||||
|
|
||||||
|
Then retrieve the new page resource with something like:
|
||||||
|
|
||||||
|
{{< code file=layouts/_default/single.html >}}
|
||||||
|
{{ with .Resources.Get "cover.jpg" }}
|
||||||
|
<img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
|
||||||
|
{{ end }}
|
||||||
|
{{< /code >}}
|
||||||
|
|
||||||
|
###### Site
|
||||||
|
|
||||||
|
Returns the `Site` to which the pages will be added.
|
||||||
|
|
||||||
|
{{< code file=content/books/_content.gotmpl >}}
|
||||||
|
{{ .Site.Title }}
|
||||||
|
{{< /code >}}
|
||||||
|
|
||||||
|
###### Store
|
||||||
|
|
||||||
|
Creates a persistent “scratch pad” to store and manipulate data. See [examples](/methods/page/store/).
|
||||||
|
|
||||||
|
{{< code file=content/books/_content.gotmpl >}}
|
||||||
|
{{ .Store.Set "key" "value" }}
|
||||||
|
{{ .Store.Get "key" }}
|
||||||
|
{{< /code >}}
|
||||||
|
|
||||||
|
###### EnableAllLanguages
|
||||||
|
|
||||||
|
By default, Hugo executes the content adapter for the language defined by the _content.gotmpl file . Use this method to activate the content adapter for all languages.
|
||||||
|
|
||||||
|
{{< code file=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 }}
|
||||||
|
{{< /code >}}
|
||||||
|
|
||||||
|
## Page map
|
||||||
|
|
||||||
|
Set any [front matter field] in the map passed to the [`AddPage`](#addpage) method, excluding `markup`. Instead of setting the `markup` field, specify the `content.mediaType` as described below.
|
||||||
|
|
||||||
|
This table describes the fields most commonly passed to the `AddPage` method.
|
||||||
|
|
||||||
|
Key|Descripion|Required
|
||||||
|
:--|:--|:-:
|
||||||
|
`content.mediaType`|The content [media type]. Default is `text/markdown`. See [content formats] for examples.|
|
||||||
|
`content.value`|The content value as a string.|
|
||||||
|
`dates.date`|The page creation date as a `time.Time` value.|
|
||||||
|
`dates.expiryDate`|The page expiry date as a `time.Time` value.|
|
||||||
|
`dates.lastmod`|The page last modification date as a `time.Time` value.|
|
||||||
|
`dates.publishDate`|The page publication date as a `time.Time` value.|
|
||||||
|
`kind`|The [page kind]. Default is `page`.|
|
||||||
|
`params`|A map of page parameters.|
|
||||||
|
`path`|The page's [logical path] relative to the content adapter. Do not include a leading slash.|:heavy_check_mark:
|
||||||
|
`title`|The page title.|
|
||||||
|
|
||||||
|
{{% note %}}
|
||||||
|
While `path` is the only required field, we recommend setting `title` as well.
|
||||||
|
|
||||||
|
When setting the `path`, Hugo transforms the given string to a logical path. For example, setting `path` to `A B C` produces a logical path of `/section/a-b-c`.
|
||||||
|
{{% /note %}}
|
||||||
|
|
||||||
|
## Resource map
|
||||||
|
|
||||||
|
Construct the map passed to the [`AddResource`](#addresource) method using the fields below.
|
||||||
|
|
||||||
|
Key|Descripion|Required
|
||||||
|
:--|:--|:-:
|
||||||
|
`content.mediaType`|The content [media type].|:heavy_check_mark:
|
||||||
|
`content.value`|The content value as a string or resource.|:heavy_check_mark:
|
||||||
|
`name`|The resource name.|
|
||||||
|
`params`|A map of resource parameters.|
|
||||||
|
`path`|The resources's [logical path] relative to the content adapter. Do not include a leading slash.|:heavy_check_mark:
|
||||||
|
`title`|The resource title.|
|
||||||
|
|
||||||
|
{{% note %}}
|
||||||
|
If the `content.value` is a string Hugo creates a new resource. If the `content.value` is a resource, Hugo obtains the value from the existing resource.
|
||||||
|
|
||||||
|
When setting the `path`, Hugo transforms the given string to a logical path. For example, setting `path` to `A B C/cover.jpg` produces a logical path of `/section/a-b-c/cover.jpg`.
|
||||||
|
{{% /note %}}
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
Create pages from remote data, where each page represents a book review.
|
||||||
|
|
||||||
|
Step 1
|
||||||
|
: Create the content structure.
|
||||||
|
|
||||||
|
```text
|
||||||
|
content/
|
||||||
|
└── books/
|
||||||
|
├── _content.gotmpl <-- content adapter
|
||||||
|
└── _index.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Step 2
|
||||||
|
: Inspect the remote data to determine how to map key-value pairs to front matter fields.
|
||||||
|
|
||||||
|
: <https://gohugo.io/shared/examples/data/books.json>
|
||||||
|
|
||||||
|
Step 3
|
||||||
|
: Create the content adapter.
|
||||||
|
|
||||||
|
{{< code file=content/books/_content.gotmpl copy=true >}}
|
||||||
|
{{/* Get remote data. */}}
|
||||||
|
{{ $data := dict }}
|
||||||
|
{{ $url := "https://gohugo.io/shared/examples/data/books.json" }}
|
||||||
|
{{ with resources.GetRemote $url }}
|
||||||
|
{{ with .Err }}
|
||||||
|
{{ errorf "Unable to get remote resource %s: %s" $url . }}
|
||||||
|
{{ else }}
|
||||||
|
{{ $data = . | transform.Unmarshal }}
|
||||||
|
{{ end }}
|
||||||
|
{{ else }}
|
||||||
|
{{ errorf "Unable to get remote resource %s" $url }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{/* Add pages and page resources. */}}
|
||||||
|
{{ range $data }}
|
||||||
|
|
||||||
|
{{/* Add page. */}}
|
||||||
|
{{ $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 }}
|
||||||
|
|
||||||
|
{{/* Add page resource. */}}
|
||||||
|
{{ $item := . }}
|
||||||
|
{{ with $url := $item.cover }}
|
||||||
|
{{ with resources.GetRemote $url }}
|
||||||
|
{{ with .Err }}
|
||||||
|
{{ errorf "Unable to get remote resource %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 "Unable to get remote resource %s" $url }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
|
{{< /code >}}
|
||||||
|
|
||||||
|
Step 4
|
||||||
|
: Create a single page template to render each book review.
|
||||||
|
|
||||||
|
{{< code file=layouts/books/single.html copy=true >}}
|
||||||
|
{{ define "main" }}
|
||||||
|
<h1>{{ .Title }}</h1>
|
||||||
|
|
||||||
|
{{ with .Resources.GetMatch "cover.*" }}
|
||||||
|
<img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="{{ .Params.alt }}">
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
<p>Author: {{ .Params.author }}</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
ISBN: {{ .Params.isbn }}<br>
|
||||||
|
Rating: {{ .Params.rating }}<br>
|
||||||
|
Review date: {{ .Date | time.Format ":date_long" }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{{ with .GetTerms "tags" }}
|
||||||
|
<p>Tags:</p>
|
||||||
|
<ul>
|
||||||
|
{{ range . }}
|
||||||
|
<li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
|
||||||
|
{{ end }}
|
||||||
|
</ul>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ .Content }}
|
||||||
|
{{ end }}
|
||||||
|
{{< /code >}}
|
||||||
|
|
||||||
|
## Multilingual sites
|
||||||
|
|
||||||
|
With multilingual sites you can:
|
||||||
|
|
||||||
|
1. Create one content adapter for all languages using the [`EnableAllLanguages`](#enablealllanguages) method as described above.
|
||||||
|
2. Create content adapters unique to each language. See the examples below.
|
||||||
|
|
||||||
|
### Translations by file name
|
||||||
|
|
||||||
|
With this site configuration:
|
||||||
|
|
||||||
|
{{< code-toggle file=hugo >}}
|
||||||
|
[languages.en]
|
||||||
|
weight = 1
|
||||||
|
|
||||||
|
[languages.de]
|
||||||
|
weight = 2
|
||||||
|
{{< /code-toggle >}}
|
||||||
|
|
||||||
|
Include a language designator in the content adapter's file name.
|
||||||
|
|
||||||
|
```text
|
||||||
|
content/
|
||||||
|
└── books/
|
||||||
|
├── _content.de.gotmpl
|
||||||
|
├── _content.en.gotmpl
|
||||||
|
├── _index.de.md
|
||||||
|
└── _index.en.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Translations by content directory
|
||||||
|
|
||||||
|
With this site configuration:
|
||||||
|
|
||||||
|
{{< code-toggle file=hugo >}}
|
||||||
|
[languages.en]
|
||||||
|
contentDir = 'content/en'
|
||||||
|
weight = 1
|
||||||
|
|
||||||
|
[languages.de]
|
||||||
|
contentDir = 'content/de'
|
||||||
|
weight = 2
|
||||||
|
{{< /code-toggle >}}
|
||||||
|
|
||||||
|
Create a single content adapter in each directory:
|
||||||
|
|
||||||
|
```text
|
||||||
|
content/
|
||||||
|
├── de/
|
||||||
|
│ └── books/
|
||||||
|
│ ├── _content.gotmpl
|
||||||
|
│ └── _index.md
|
||||||
|
└── en/
|
||||||
|
└── books/
|
||||||
|
├── _content.gotmpl
|
||||||
|
└── _index.md
|
||||||
|
```
|
||||||
|
|
||||||
|
[content formats]: /content-management/formats/#classification
|
||||||
|
[front matter field]: /content-management/front-matter/#fields
|
||||||
|
[logical path]: /getting-started/glossary/#logical-path
|
||||||
|
[media type]: https://en.wikipedia.org/wiki/Media_type
|
||||||
|
[page kind]: /getting-started/glossary/#page-kind
|
||||||
|
[syntax]: /templates/introduction/
|
||||||
|
[template functions]: /functions/
|
@ -29,7 +29,7 @@ content/
|
|||||||
|
|
||||||
Regardless of content format, all content must have [front matter], preferably including both `title` and `date`.
|
Regardless of content format, all content must have [front matter], preferably including both `title` and `date`.
|
||||||
|
|
||||||
Hugo selects the content renderer based on the `markup` identifier in front matter, falling back to the file extension. See the [comparison table](#comparison) table below for a list of markup identifiers and recognized file extensions.
|
Hugo selects the content renderer based on the `markup` identifier in front matter, falling back to the file extension. See the [classification](#classification) table below for a list of markup identifiers and recognized file extensions.
|
||||||
|
|
||||||
## Formats
|
## Formats
|
||||||
|
|
||||||
@ -99,16 +99,16 @@ Hugo passes these CLI flags when calling the rst2html executable:
|
|||||||
--leave-comments --initial-header-level=2
|
--leave-comments --initial-header-level=2
|
||||||
```
|
```
|
||||||
|
|
||||||
## Comparison
|
## Classification
|
||||||
|
|
||||||
Content format|Identifier|Identifier aliases|File extensions
|
Content format|Media type|Identifier|File extensions
|
||||||
:--|:--|:--|:--
|
:--|:--|:--|:--
|
||||||
Markdown|`goldmark`|`md`, `mdown`, `markdown`|`md`, `mdown`, `markdown`
|
Markdown|`text/markdown`|`markdown`|`markdown`,`md`, `mdown`
|
||||||
HTML|`html`|`htm`|`html`, `htm`
|
HTML|`text/html`|`html`|`htm`, `html`
|
||||||
Emacs Org Mode|`org`||`org`
|
Emacs Org Mode|`text/org`|`org`|`org`
|
||||||
AsciiDoc|`asciidocext`|`adoc`, `ad`|`adoc`, `ad`
|
AsciiDoc|`text/asciidoc`|`asciidoc`|`ad`, `adoc`, `asciidoc`
|
||||||
Pandoc|`pandoc`|`pdc`|`pandoc`, `pdc`
|
Pandoc|`text/pandoc`|`pandoc`|`pandoc`, `pdc`
|
||||||
reStructuredText|`rst`||`rst`
|
reStructuredText|`text/rst`|`rst`|`rst`
|
||||||
|
|
||||||
When converting content to HTML, Hugo uses:
|
When converting content to HTML, Hugo uses:
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ lang
|
|||||||
|
|
||||||
(`string`) An identifier corresponding to one of the supported [content formats]. If not provided, Hugo determines the content renderer based on the file extension.
|
(`string`) An identifier corresponding to one of the supported [content formats]. If not provided, Hugo determines the content renderer based on the file extension.
|
||||||
|
|
||||||
[content formats]: /content-management/formats/#comparison
|
[content formats]: /content-management/formats/#classification
|
||||||
|
|
||||||
###### menus
|
###### menus
|
||||||
|
|
||||||
|
@ -90,6 +90,10 @@ Command line interface.
|
|||||||
|
|
||||||
An [array](#array), [slice](#slice), or [map](#map).
|
An [array](#array), [slice](#slice), or [map](#map).
|
||||||
|
|
||||||
|
###### content adapter
|
||||||
|
|
||||||
|
A template that dynamically creates pages when building a site. For example, use a content adapter to create pages from a remote data source such as JSON, TOML, YAML, or XML. See [details](/content-management/content-adapters/).
|
||||||
|
|
||||||
###### content format
|
###### content format
|
||||||
|
|
||||||
A markup language for creating content. Typically Markdown, but may also be HTML, AsciiDoc, Org, Pandoc, or reStructuredText. See [details](/content-management/formats/).
|
A markup language for creating content. Typically Markdown, but may also be HTML, AsciiDoc, Org, Pandoc, or reStructuredText. See [details](/content-management/formats/).
|
||||||
|
@ -82,6 +82,20 @@ The path separators (slash or backslash) in `Path`, `Dir`, and `Filename` depend
|
|||||||
{{ end }}
|
{{ end }}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
###### IsContentAdapter
|
||||||
|
|
||||||
|
{{< new-in 0.126.0 >}}
|
||||||
|
|
||||||
|
(`bool`) Reports whether the file is a [content adapter].
|
||||||
|
|
||||||
|
[content adapter]: /content-management/content-adapters/
|
||||||
|
|
||||||
|
```go-html-template
|
||||||
|
{{ with .File }}
|
||||||
|
{{ .IsContentAdapter }}
|
||||||
|
{{ end }}
|
||||||
|
```
|
||||||
|
|
||||||
###### LogicalName
|
###### LogicalName
|
||||||
|
|
||||||
(`string`) The file name.
|
(`string`) The file name.
|
||||||
@ -159,6 +173,7 @@ ContentBaseName|a|b|news
|
|||||||
Dir|news/|news/b/|news/
|
Dir|news/|news/b/|news/
|
||||||
Ext|md|md|md
|
Ext|md|md|md
|
||||||
Filename|/home/user/...|/home/user/...|/home/user/...
|
Filename|/home/user/...|/home/user/...|/home/user/...
|
||||||
|
IsContentAdapter|false|false|false
|
||||||
LogicalName|a.en.md|index.en.md|_index.en.md
|
LogicalName|a.en.md|index.en.md|_index.en.md
|
||||||
Path|news/a.en.md|news/b/index.en.md|news/_index.en.md
|
Path|news/a.en.md|news/b/index.en.md|news/_index.en.md
|
||||||
Section|news|news|news
|
Section|news|news|news
|
||||||
|
@ -47,5 +47,5 @@ Render with [Pandoc]:
|
|||||||
{{ .RenderString $opts $s }} → <p>H<sub>2</sub>O</p>
|
{{ .RenderString $opts $s }} → <p>H<sub>2</sub>O</p>
|
||||||
```
|
```
|
||||||
|
|
||||||
[markup identifier]: /content-management/formats/#formats
|
[markup identifier]: /content-management/formats/#classification
|
||||||
[pandoc]: https://www.pandoc.org/
|
[pandoc]: https://www.pandoc.org/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user