Suggest a better way

I wanted to use the content from 2 markdown pages (‘about’ and ‘mission’) as a an intro on the site’s front page, which lists posts. The posts in the site can be pretty weird so it really seemed like a front page for the site was needed but I still want linkable “about” and “mission” in the top-level menu. I definitely want to reuse the content without copying and pasting the markdown from those pages into _index.md for the site.

I created a shortcode called intro.html to grab the content of those 2 pages like this:


<div>

    {{ range $.Site.Pages }}
        {{ if (eq .Title "About") }}
            {{ .Content }}
        {{ end }}
        {{ if (eq .Title "Mission") }}
            {{ .Content }}
        {{ end }}
    {{ end }}

</div>

I then display it on _index.md at the top level of the content folder thusly:

---
title: Overview
---

<h2>Overview</h2>

{{<  intro   >}}

<hr/>

<h1>Recent Posts...</h1>

It works:

Wondering:

  • Is seems a little lame. There is no time hit for the visitor to the site because it happens at build time. With a tiny number of pages it’s fast: 32ms. (Go Hugo) Still, I go through all pages to find 2 pages.
  • Is there any way to index directly to a specific page and get its content? Sort of like $.Site.Pages.Mission.Content – of course this is wrong. .Site.Pages is an array. There would have to be a Dict with keys that are title (or name would do). Or a function…? There is still a loop to go through but if a Dict is a hash in Go (assume so) it would really be direct access. Is there a Dict of pages or other such collection? It’s not a really a speed thing. Seems like there should be some way to plop the content of page somewhere by just referencing the page.
  • Seems like I probably need a different layout for the landing page. I would NOT want to cut and past the about and mission content into a layout – that would be a bad munging of format and content. Other templates in other themes often have front matter for ‘feature_image’, which takes an image file name as a value. This would be a layout with front matter used for ‘intro’, which would take a filename or page name (better) and use the content–and would accept an array. Seems like it would not be that hard to create such a page layout and use it as index.html for the site.

What I have works? Would you do it differently? Anything like this in a theme you’ve seen or used? Nothing wrong with what I’ve done, just felt like there might have been a more direct way like a shortcode to grab a page’s content.

I love, love, love Mainroad theme!

Found it. I did search before posting, but I didn’t pick such good search terms.

Searched again and found .Site.GetPage and the use of {{ with …}}, which is sort of the universal way in Go templates to do something with what you’ve found (Python has with, but more for anonymous functions…). Someone else did something similar with .Page.Resource.GetMatch but .GetPage is perfect.

So now it’s like this:

<div>

  {{ with $.Site.GetPage "/about" }}{{ .Content }}{{ end }}
  {{ with $.Site.GetPage "/mission" }}{{ .Content }}{{ end }}

</div>

I saved a whole millisecond! (I said it wasn’t about speed…)

This is perfect. Love it.

layouts/shortcodes/get-content.html

{{ range $file := .Params }}
  {{ with site.GetPage $file }}
    {{ .Content }}
  {{ else }}
    {{ errorf "The %s shortcode was unable to find the %s page. See %s" $.Name $file $.Position }}
  {{ end }}
{{ else }}
  {{ errorf "The %s shortcode requires one or more positional parameters. See %s" $.Name $.Position }}
{{ end }}

markdown

{{< get-content "about" "mission" "whatever" >}}

Nice. More versatile with shortcode input arguments.

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