Creating a shortcode for manually specified related content

Hi,

I’m working on a shortcode to display related content. It’s designed like this:

{{<related elements="input() integer float string symbol resolution session source">}}

Here I specify the name of the posts that I want to have listed, separated by a space. This works for me since all of my post titles are single words.

The shortcode code is:

{{ $related := .Get "elements" }}
{{ $category := index .Page.Params.categories 0 }}
  
<dl>
{{ range $.Page.Site.Pages }}

  {{ if isset .Params "categories" }}
      {{ if and (eq (index .Params.categories 0) $category) (in .Title $related) }}
      
        <dt><a href="{{ .Permalink }}"><code>{{ .Title }}</code></a></dt>
        <dd>{{ .Description | markdownify }}</dd>
      
      {{ end }}
  {{ end }}

{{ end }}
</dl>

Here I loop through all pages and look whether a .Title happens in the list of posts passed to the shortcode.

This shortcode only works when I specify one ‘related element’ like this:

{{<related elements="input()">}}

With more posts specified, it doesn’t work. I can understand that (there’s one loop after all), but I don’t see how to code should be so that it does work. Can someone help me?

Also, my second question: is it possible to pull the .Description from a post? Given how my site is structured, I already know the post title that I want to display in the related list. I also know that post’s permalink. What I don’t know is that post’s .Description. If I can get that without looping repeatedly over all posts, for every post, that would be great for my Hugo site build performance.

I learned here that arrays cannot be passed to a shortcode, so I’ve opted for adding the titles of the related content in the front matter like this:

related = ["blue", "black", "green"]

My test shortcode is now:

{{ $related := .Page.Params.related }}

<dl>

{{ range $.Page.Site.Pages }}

    {{ $same_content := intersect $related .Pages | len | lt 0 }}

{{ end }}
</dl>

Here I get the problem that .Pages is not a struct of *hugoLib.Page, but with .Site.Pages I get the error that intersect cannot iterate over *hugoLib.Pages.

Any idea or suggestion? Thanks.

1 Like