Multiple Content parts within the same page

I would like to be able to write several parts of my content in markdown, all in the same page content file. I want this content to be in markdown because it has to be amendable by anybody without any html/hugo knowledge (for the marketing people writing the content).

Having only one content part to use per page might be ok for a blog where a post is usually a long block of text, but for a website where you have several different parts, there seems to be something missing here.

What would be great would be something like:

+++
title = "my page"
+++

~~~ intro ~~~
blabla
# this is pure markdown
- yes
- no
~~~

~~~ aside ~~~
*blablabla*
## still pure markdown
~~~

~~~ testimonials[] ~~~
my first customer
~~~

~~~ testimonials[] ~~~
my second customer
~~~

~~~ content ~~~
blabla
~~~

and then be able in my layout to use: {{.Content.intro}}, {{.Content.aside}}, loop over all {{.Content.testimonials}} …

I see several other ways to achieve something similar at the moment (shortcodes, variables in front matter, split content into several md files, extra content stored in data or layout, texts hardcoded in the template), but no solution seems to be as easy to use and write as this one: having all content of a page in the same file, that can be written in pure markdown (by anybody).

I’m new to Hugo so perhaps something similar can already be achieved with the same goal, I’ll be glad to be enlightened on this matter!

1 Like

I would make an excel file and use something like excel-as-json to export it to json and use that as a data template which you can then loop through to display it on your template.

That seems like the easiest route for those who have no html/markdown knowledge.

Good luck.

Thanks for the info, I didn’t think of that possibility.

What is edited is real page content though, not data, so it ought to live inside the content/ folder. Any other way, or anybody happy with my feature suggestion?

Another option is making a section for testimonials for example and inserting a new .md file for each testimonial and looping through those in your template in order to display them.

Users can then add/edit them in the testimonial section using markdown.

That is a solution I pondered as discussed here: Load multiple content files in a single template
where you need to set the layout to “empty”.

This feels like a hack and moreover it splits the content of the page into multiple files. If I reuse my testimonials for no page other than the homepage, why would it be separated?
What about the “intro” and “aside” content that appear in my example. They would need to be stored in separate files even though they relate only to my home page for instance?

If I wanted to recreate such a page for instance with Hugo, how would I store the content?

I browsed through the Hugo templates gallery and found that very few can show content other than a single block of text per page. I believe it’s because Hugo doesn’t make it easy.

Being able to store multiple parts of content within the same document would make it easy to achieve such a thing. The layout for the page would just fetch the content parts by their name.

Related content within the same document + no hard coded texts in the layout = easy to edit.

Another option is using page params but that can get messy at least I wouldn’t opt for it. This way all your content would be in the same markdown file.

You can make an array of testimonials something like this:

testimonials = ["testimonial 1", "testimonial 2", "etc"]

Then loop through that in your template using the Params.testimonials

That’s another option I investigated, but as you said it’s messy to mix markdown content that can get quite long within the front matters.
The content left in the “markdown” part of the file would be no different/more important from/than the other parts, but in usage it would be different.
That feels like a hack again.

There’s currently one main content per page. We need to have several ones. That’s what most website pages apart from blogs require.

I’m also interested to know whether there is a decent solution for this problem in Hugo yet?

1 Like

On the thread Single page with nested content - #16 by rdwatters in April @rdwatters said:

Hugo has developed a number of really powerful features in the last 13 months. It’s very easy to add markdown content to a single page in a variety of ways.

Perhaps start a new thread?

Would you care to elaborate in this thread? My particular need is for multiple chunks of Markdown content on a single page (in different regions of the page).

Here’s a description of what’s needed: “blocks” and how other CMSes handle it:

There are many, many ways to get single page layouts in Hugo. One can combine multiple pieces of content, or generate it from one single piece. There are examples of these methods in the theme showcase.

Create a single, long HTML document from markdown is possible, but not what it is made for. HTML is made for that, of which markdown provides a subset of functionality.

It sounds like you have an aversion to a modular structure for your site’s content. That is completely valid, but it also means that complexity has to be consolidated into that one file. A lovely, convincing landing page is going to be complex if it has anything aside from block level elements, primarily paragraphs. Anything else, and you have to put the complexity somewhere.

Hugo makes it easy to put that complexity into layout templates, and that informs the design of systems (each theme or site built with Hugo). So while it is possible to build Hugo templates in a way that keeps all the content in one markdown file, there isn’t much benefit of Hugo if all you want is one well crafted page. There are better tools for that, and considering that files in static are copied over directly, you can even use those tools to generate the pages for your Hugo site. :slight_smile:

1 Like

I have this similar need. I have different blocks within the same realm that should live together – and the template should decide how to use the data in the design. I can, of course use the same markdown and format them, but I might want to reorder different blocks in the future.

I tried putting everything in Params and using markdownify, and this works well enough that I’m okay with it, with one exception – I don’t need many shortcodes, but ref/relref would be great in maintaining the same consistency.

1 Like

Larry, if you’re still around, would you mind explaining a bit more how you did that? I’m new to Hugo and found this thread. I think I’d be okay with that Params solution, but I’m not sure how it works exactly. Could you give me a code sample? Thanks a lot.

You guys should check out page bundles/page resources.

Any files can go in there, including .md which you can use in your template as any other page.

That’s how I would do it now. You can add as many .md to a page bundle as needed and use their own front matter to define what their are (section, blocks etc…)

1 Like

Page bundles look interesting, thanks @regis.

A problem though (excerpt from the documentation):

Note that the home page bundle cannot contain other content pages, but other files (images etc.) are fine.

Too bad, the home page is typically the kind of page where this feature would be the most needed… Will this improve in future versions ? (it’s the only thing that prevents me from using Hugo).

1 Like

You can mark bundles as headless and use them in the home page:

/content/home_pages

index.md => headless: true
page1.md
page2.md

etc.

And in your home page template:

{{ $bundle := .Site.GetPage "page" "home_pages" }}
{{ range $bundle.Resources.ByType "page"  }}
{{ .Title }}: {{ .Content }}
{{ end }}

The above is totally untested, but should work.

8 Likes

It works. Been doing it myself.

3 Likes

This is great, thanks very much!

I am trying to solve a similar but slightly more complex issue and can’t find a solution. Instead of a home page with several differently styled content parts I am trying to create an “industry” template and use it for different industries. Each industry page then contains different content parts which should be styled differently.

Using your suggestion above, I would create e.g. a “health” html template and regarding content I would have the following files:

  • content/health/index.md
  • content/health/content1.md
  • content/health/content2.md

In the “health” html template I would use

{{ $headlessBundle := .Site.GetPage "health" }}
{{ $contentSnippet := $headlessBundle.Resources.Match "content1.md" }}
{{ range $contentSnippet }}
{{ .Content }}
{{ end }}

This works.

However, I do not want to have a html template for each industry (e.g. “health”) but instead a generic html template called “industry.html” as all industry pages should look similar (same structure). Having such an “industry” html template I can’t use the above code anymore as the first code line should get an industry page like {{ $headlessBundle := .Site.GetPage "health" }}. Here I would need something like a dynamic industry variable that I could use to get the desired page, e.g. “health”, dependent on what url got initially requested. Something like {{ $headlessBundle := .Site.GetPage "{{ VARIABLE_GOES_HERE }}" }}

I hope you can understand what I am trying to say and to accomplish and would like to kindly ask, if you or anyone in this thread might have a solution proposal.

Thanks very much to everyone in advance,
Sebastian