I will update the content of this post if appropriate. So, if you have a better solution, I’m happy for your comment.
After spending a long night and not finding a good solution in the discussion forums, here is my little How To on building a single content file from content partial files.
It references:
- Referencing Files from within .Content
- Creating ‘static’ content that uses partials
- Hugo Shortcode to generate other content in current content page
- Huge problems with DRY because content files don’t support any logic (like including small partials)
The Problem:
How to build a content file from multiple content partials? But within the content folder, not from layout partials. That means, the composed content is pulled into the layout template via a single {{ .Content }}
in your layout template.
The Goal:
Compose the content file without messing with the layout templates of a Hugo theme. This makes it easy to separate the concerns of content creators from the designers. The content partials should not show up as single pages.
The general steps are:
- create a
partials/
directory withincontent/
and make it a headless bundle, which means, the content of this folder does not show up as single pages - create a custom shortcode to include files within another content file
- compose your content file
I ended up with the following folder structure (this example uses .html
files, but it works the same with .md
files):
content/
partials/
index.md
part-1.html
part-2.html
no-show.html <-- test file for headless content
index.html
layout/
shortcodes/
include.html
index.html
The index.html
file is used to compose the content.
---
file: index.html
---
<h1>Hello index file<h1>
{{ include "partials" "part-1.html"}}
<p>And here follows part 2:</p>
{{ include "partials" "part-2.html"}}
<p>Lots of other content in index.html</p>
The partial files are used to split the content in smaller sections. These files should not show up in the exported public/
folder and generate no permalink.
---
file: part-1.html
---
<h2>Part 1</h2>
<p>Very interesting.</p>
---
file: part-2.html
---
<h2>Part 2</h2>
<p>Lorem Ipsum...</p>
To make the content/partials/
directory not show up in the page structure, define the folder as headless bundle within content/partials/index.md
:
---
headless: true
---
Now on to the shortcode. Within layout/shortcodes/
create a file named include.html
. The name of this file will be the name of the shortcode command:
{{ $dir := .Get 0 }}
{{ $file := .Get 1 }}
{{ $headless := .Site.GetPage $dir }}
{{ $include := $headless.Resources.GetMatch $file }}
{{ $include.Content }}
I tried to build the shortcode with just 1 parameter, but
.Site.GetPage
only seems to find the headless directory, not the files within. Any thoughts on that?