The same content can be relevant in several places.
Here is how to include one file in multiple pages using Hugo Shortcodes.
Requirements
Here is what I’ve been searching for:
- The solution must support content written both in Markdown and HTML
- The Front Matter from the included file should not be displayed
- Optional: do not display included files on the homepage
Solution
Create a file called layouts/shortcodes/include.html
with this content:
{{ $file := .Get 0 }}
{{ (printf "%s%s" .Page.File.Dir $file) | readFile | replaceRE "^---[\\s\\S]+?---" "" | safeHTML }}
Usage
{{% include "included-file-name.md" %}}
Results
- Works fine!
- Markdown content is properly rendered.
- The filename is enough (no fullpath is required)
- HTML is rendered, at least with
unsafe: true
in the config file. - The Front Matter of the included file is properly hidden. Thanks to @shafiemukhre.
- Using
draft: true
is used to hide included files from the homepage.
Caveats
- When editing the included file, the page including this file is not automatically updated. Restarting the server is required.
- Does not work if the included file starts with
<div>
: Hugo crashed with an error “plain HTML documents not supported”
Roadmap
- experiment with
.RawContent
instead of trimming front matter
Archives
Before finding the right solution, I’ve been testing the following methods:
Iteration #1
Create the following file in layouts/shortcodes/include.html
:
{{ $file := .Get 0 }}
{{ $file | readFile | safeHTML }}
Call with {{% include "/content/article/included-file-name.md" %}}
Results:
- Markdown content is properly rendered.
- HTML is rendered, at least with
unsafe: true
. Note that Hugo must be restarted to see the HTML modifications - Does not work if the included file starts with
<div>
: Hugo crashed with an error “plain HTML documents not supported”
Iteration #2
Same as above but the relative filepath is enough (no full path)
Usage: {{% include "included-file-name.md" %}}
Code:
{{ $file := .Get 0 }}
{{ (printf "%s%s" .Page.File.Dir $file) | readFile | safeHTML }}
Results:
Same as Iteration #1. Relative file path is now enough.
Iteration #3
Still in layouts/shortcodes/include.html
:
{{ $base_path := $.Page.Dir }}
{{ $file_path := .Get 0 }}
{{ $full_file_path := (path.Join $base_path $file_path) }}
{{ readFile $full_file_path | markdownify | safeHTML }}
Call with {{< include "included-file-name.md" >}}
(Note that we switch from {{% %}}
to {{< >}}
)
Results:
Same as Iteration #2
Iteration #4
{{ (site.GetPage $file).RawContent }}
{{ $filepath := printf "%s%s" .Page.File.Dir $file }}
{{ (site.GetPage $filepath).RawContent }}
{{- with $.Page.Resources.GetMatch $file -}}
{{- .Content -}}
{{- end -}}
{{ with site.GetPage $filepath}}
{{ .RawContent }}
{{ end }}
{{ with .Site.GetPage $filepath }}{{.Content}}{{end}}
Other methods untested so far
- https://www.docsy.dev/docs/adding-content/shortcodes/#include-external-files
- https://it.knightnet.org.uk/kb/hugo/hugo-snippets/#shortcode-to-render-a-code-example-in-a-page-post
- https://doc.huc.fr.eu.org/en/web/hugo/hugo-shortcodes/#file
- https://oostens.me/posts/hugo-include-file-shortcode/