Best Practice for Multiple Content Areas on a Page?

In developing my second site with Hugo, the client is wanting to have several subsections on the main page that are editable. In the past, we solved this in Grav using module templates and the client would log on to the Grav admin and edit the content of each sub-module to change sub-section on the home page. Tweaks to placement could be made in the front-matter.

In Hugo, I want to do something like this in the home page:

// This is pseudo-code not functional code
{{define main}}
{{ if .Params.sub1on }}{{ .Sub1Content }}{{ end }}
{{ if .Params.sub2on }}{{ .Sub2Content }}{{ end }}
{{ .Content }}
{{ end }}

This isn’t exactly “sections”, as I currently understand them (perhaps they are?), because you wouldn’t go to /sub1content as a page at any time.

My first stab at solving this was to use local resources (.txt) pages:

{{ define main }}

{{ with .Resources.GetMatch "gala.txt"  }}
<div class="container mt-5">
    <div class="row">
        <div class="col col-12 col-md-6">
            {{ .Content | markdownify }}
        </div>
        <div class="col">
...

And it works perfectly well. The client can commit changes to /gala.txt (in markdown) and the home page will change appropriately. And if the txt file is not found, the section is effectively turned off. This particular example is for semi-annual content that comes and goes with bespoke content each time.

But, I can’t help but wonder. Is there a “more Hugo correct” way of doing this?

Thanks.

1 Like

Pass .Content through $.Page.RenderString instead.

No, it is not.

Without | markdownify:

With | markdownify:

I think I was editing my post while you were responding.

If your client includes links, images, or headings, and if you have created render hooks, markdownify will not fire the render hooks. The .RenderString method on .Page will.

OK, clarified, thanks.

You can also do this:

content/post/
└── test/
    ├── gala.md
    └── index.md  

In a leaf bundle, any file other than index.md is a resource. If it is a markdown file the .Content is fully rendered. This is better than passing a string through markdownify or .Page.RenderString because shortcodes are rendered as well.

Although this is not relevant to your current task, there are differences between a markdown file as a page resource (.Resources.GetMatch) and a markdown file as a global resource (resources.GetMatch). See this issue.

Right, but we’re not in a leaf bundle at the root index page by definition.

/
|__ _index.md
      gala.txt
      scholarships.txt

If I change those to markdown or html, Hugo decides they are pages and makes them addressable (which is not what I want to happen). Similarly, if I build out something like:

/
|__ _index.md
    |__ subcontent/
        |__ gala.md
            scholarships.md

I made that into a headless bundle:

/
|__ _index.md
    |__ subcontent/
        |__ index.md => headless = true
            gala.md
            scholarships.md

Which I thought might work, but it did not, at least with this call:

<div>
    <h1>.Site.GetPage "subcontent/gala"</h1>
    {{ with .Site.GetPage "/subcontent/gala" }}
    {{ .Content }}
    {{ end }}

    <h1>.Resources.GetMatch "subcontent/gala.md"</h1>
    {{ with .Resources.GetMatch "/subcontent/gala.md" }}
    {{ .Content }}
    {{ end }}
</div>

I feel this is close to some kind of solution…

I understand that, which is I why I included a tree diagram, but I fear I confused the issue instead of providing useful information.

Correct. The first table on this page does a pretty good job of describing the differences between leaf and branch bundles.

Good idea.

content/
├── subcontent/
│   ├── gala.md
│   ├── index.md
│   └── scholarships.md
└── _index.md

content/subcontent/index.md

headless = true

home page template

{{ $p := site.GetPage "subcontent" }}
{{ range $p.Resources.Match "*.md" }}
  {{ .Content }}
{{ end }}

Thank you. Working as desired with a bit of specificity per section:

{{ $p := site.GetPage "subcontent" }}
{{ with $p.Resources.GetMatch "gala.md" }}
    {{ .Content }}
{{ end }}

Even renders out the shortcakes [EDIT: shortcakes? shortcodes.] properly, which. is. great.

Thank you.

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.