+
+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" }}
+ {{ .Title }}
+
+ {{ with .Resources.GetMatch "cover.*" }}
+
+ {{ end }}
+
+ Author: {{ .Params.author }}
+
+
+ ISBN: {{ .Params.isbn }}
+ Rating: {{ .Params.rating }}
+ Review date: {{ .Date | time.Format ":date_long" }}
+
+
+ {{ with .GetTerms "tags" }}
+ Tags:
+
+ {{ 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/
diff --git a/content/en/content-management/formats.md b/content/en/content-management/formats.md
index 305679b21..7b141593c 100644
--- a/content/en/content-management/formats.md
+++ b/content/en/content-management/formats.md
@@ -29,7 +29,7 @@ content/
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
@@ -99,16 +99,16 @@ Hugo passes these CLI flags when calling the rst2html executable:
--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`
-HTML|`html`|`htm`|`html`, `htm`
-Emacs Org Mode|`org`||`org`
-AsciiDoc|`asciidocext`|`adoc`, `ad`|`adoc`, `ad`
-Pandoc|`pandoc`|`pdc`|`pandoc`, `pdc`
-reStructuredText|`rst`||`rst`
+Markdown|`text/markdown`|`markdown`|`markdown`,`md`, `mdown`
+HTML|`text/html`|`html`|`htm`, `html`
+Emacs Org Mode|`text/org`|`org`|`org`
+AsciiDoc|`text/asciidoc`|`asciidoc`|`ad`, `adoc`, `asciidoc`
+Pandoc|`text/pandoc`|`pandoc`|`pandoc`, `pdc`
+reStructuredText|`text/rst`|`rst`|`rst`
When converting content to HTML, Hugo uses:
diff --git a/content/en/content-management/front-matter.md b/content/en/content-management/front-matter.md
index 8ea41487d..2c01f7854 100644
--- a/content/en/content-management/front-matter.md
+++ b/content/en/content-management/front-matter.md
@@ -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.
-[content formats]: /content-management/formats/#comparison
+[content formats]: /content-management/formats/#classification
###### menus
diff --git a/content/en/getting-started/glossary.md b/content/en/getting-started/glossary.md
index e31f45187..bbc35906e 100644
--- a/content/en/getting-started/glossary.md
+++ b/content/en/getting-started/glossary.md
@@ -90,6 +90,10 @@ Command line interface.
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
A markup language for creating content. Typically Markdown, but may also be HTML, AsciiDoc, Org, Pandoc, or reStructuredText. See [details](/content-management/formats/).
diff --git a/content/en/methods/page/File.md b/content/en/methods/page/File.md
index 310404cb8..d59171577 100644
--- a/content/en/methods/page/File.md
+++ b/content/en/methods/page/File.md
@@ -82,6 +82,20 @@ The path separators (slash or backslash) in `Path`, `Dir`, and `Filename` depend
{{ 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
(`string`) The file name.
@@ -159,6 +173,7 @@ ContentBaseName|a|b|news
Dir|news/|news/b/|news/
Ext|md|md|md
Filename|/home/user/...|/home/user/...|/home/user/...
+IsContentAdapter|false|false|false
LogicalName|a.en.md|index.en.md|_index.en.md
Path|news/a.en.md|news/b/index.en.md|news/_index.en.md
Section|news|news|news
diff --git a/content/en/methods/page/RenderString.md b/content/en/methods/page/RenderString.md
index 0f2df111f..1a92c78c6 100644
--- a/content/en/methods/page/RenderString.md
+++ b/content/en/methods/page/RenderString.md
@@ -47,5 +47,5 @@ Render with [Pandoc]:
{{ .RenderString $opts $s }} → H2O
```
-[markup identifier]: /content-management/formats/#formats
+[markup identifier]: /content-management/formats/#classification
[pandoc]: https://www.pandoc.org/