How would you clean up this template code?

This works fine, but is very verbose. And lots of brackets. Any ideas?

I’m reading headings (“tags”) and page slugs (“topics”) from a data file. I only want to create each heading if the named pages actually exist.

      {{ range $tag := .Site.Data.tags }}
        {{ $topics := index $tags_and_topics $tag }}

        {{/*                                               */}}
        {{/* Skip this tag if there are no pages under it. */}}
        {{/*                                               */}}

        {{ $has_a_page := false }}
        {{ range $topic := $topics }}
          {{ $topic_slug := lower (replace $topic " " "-") }}
          {{ $page       := $.Page.GetPage $topic_slug }}
            {{ if $page }}
              {{ $has_a_page = true }}
            {{ end }}
        {{ end }}
        {{ if not $has_a_page }}
          {{ continue }}
        {{ end }}

        <h2>{{ i18n $tag }}</h2>          
        <ul>
        ...
      {{ end }}

That’s difficult to answer without knowing what you’re going to do with each heading.

If you just want to print the headings:

{{ range $tag := site.Data.tags }}
  {{ range index $tags_and_topics $tag }}
    {{ if $.Page.GetPage (replace . " " "-" | lower) }}
      <h2>{{ i18n $tag }}</h2>
      {{ break }}
    {{ end }}
  {{ end }}
{{ end }}

On a related note: it appears that you are trying to use lower (replace $topic " " "-") to create slugs for your topics.

I have had great success using (urls.Anchorize | Hugo) for this exact purpose. Intuitively, I looked at urls.URLize | Hugo first, but as the really great documentation makes plain to see with examples comparing the two, anchorize is what we want here.

1 Like

Maybe I could refactor this by creating a partial for the heading with its list of pages.

And then a partial for the list of pages.

I’d first evaluate the partial for the list of pages. If it comes back empty, then skip creating the heading+pages.