How to: Build a single content file from files in a Headless Bundle with Shortcodes

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:

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 within content/ 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?

2 Likes

Terminology is what helps people grasp basic Hugo concepts.

In my opinion baptizing shortcodes that reference the contents of a Headless Bundles into content partials is a sure way to cause confusion to a new user who may read this.

So to clear things up.
Partial templates —> Smaller, context-aware components in your list and page templates that can be used economically to keep your templating DRY.

Shortcodes —> Simple snippets inside your content files calling built-in or custom templates.

Headless Bundle—> A Page Bundle that is configured to not get published anywhere

Basically the above Tips & Tricks involves creating shortcodes that reference the contents of a Headless Bundle. And you will still need to define the shortcode under layouts/shortcodes/include.html

The technique is interesting @dirkolbrich but let’s respect existing Hugo terminology please.

So, I understand that the phrasing bothers you. I know, most of these words are mostly used while developing the layout or a theme.

Which more “ubiquitous” language would you use in the context of content?

My goal is to show how to compose a longer piece of content from smaller content chunks (?). E.g. a blog post with more than 10k words or a single page documentation.

I already posted about the proper terminology of your technique above.

Also note that this is not some whim of mine.

I have seen first hand how difficult it is for a new user to understand Hugo concepts. There is really no need to muddle things up by using terms meant for something else than what this technique is about.

This Forum is a great resource and lots of people use it for reference in addition to the Docs.

I really think that calling your technique: Build a single content file from files in a Headless Bundle with Shortcodes, would be a more accurate description.

If you agree I could change the title of this topic. Also if you want you can edit your original post so that it uses the proper terms.

Sorry, I didn’t understood you first answer. I thought this were just links to the documentation. And I disagree on some parts with you.

  • renaming the post: good idea. Your wording is more precise.
  • partial template: the link leads to a section in the docs about layout. I mean content, which is a different thing for me
  • shortcodes: already used in the post as custom
  • headless bundle: used with the same meaning, and the same link to the docs

You cannot use partials in a content file unless you enable Inline Shortcodes. Partials are typically used in templates e.g. layouts/_default/single.html

The .Content variable is currently monolithic, meaning that by default it cannot be broken up into different sections.

Your technique addresses this issue by calling various files contained in a Headless Bundle via shortcodes. That’s pretty much the whole story.

Anyway I am changing the title of your post since you agreed. (I see that you already changed it. Feel free to edit your original post if you want.