Template logic for Related posts

I found a more performant code snippet dropped last August. I’ve adapted it in After Dark to support conditional list display. Here’s the end result:

{{ range first 1 (where (where .Site.Pages ".Params.tags" "intersect" .Params.tags) "Permalink" "!=" .Permalink) }}
  {{ $.Scratch.Set "has_related" true }}
{{ end }}

{{ if $.Scratch.Get "has_related" }}
  <aside>
    <header>Related Content</header>
    <ul>
      {{ $num_to_show := .Site.Params.related_content_limit | default 7 }}
      {{ range first $num_to_show (where (where .Site.Pages ".Params.tags" "intersect" .Params.tags) "Permalink" "!=" .Permalink) }}
        <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
      {{ end }}
    </ul>
  </aside>
{{ end }}

This uses uses range to loop over pages until it finds its first match, setting a Boolean in $.Scratch, which is then used to conditionally output 7 related pages, with optional limit override, in reverse chronological order (the Hugo default). Note this will grab pages across sections and not just posts.