Conditional on array length

Hi!

While trying to come up with a way of setting a link only if there is content for it, I came up with the following:

{{ $posts_item := "Articles" }}
{{ $posts := where .Data.Pages "Section" "post" | len | gt 0 }}
{{ if $posts }}
{{   $posts_item := `<a href="{{ .Site.BaseURL }}post">Articles</a>` }}
{{ end }}

This however throws the following error:

ERROR: 2015/08/08 reflect: call of reflect.Value.Type on zero Value in partials/footer.html

and $posts_item is set to “Articles”. Am I overlooking something obvious?

There is a gotcha in Go templates re. scoping of variables. Search for Scratch here and in the doc,

Thank you, I noticed scratch mentioned in another post regarding counters, I will use that strategy.

Cheers!

Hmm, I get the same error with the following code:

        {{ $posts_item := "Articles" }}
        {{ $.Scratch.Set "posts" (where .Data.Pages "Section" "post" | len) }}
        {{ if (gt ($.Scratch.Get "posts") 0) }}
        {{   $posts_item := `<a href="{{ .Site.BaseURL }}post">Articles</a>` }}
        {{ end }}

If I do

        {{ $posts_item := "Articles" }}
        {{ $.Scratch.Set "posts" 0 }}
        {{ range first 1 (where .Site.Pages "Section" "post") }}
        {{   $.Scratch.Add "posts" 1 }}
        {{ end }}
        {{ if (gt ($.Scratch.Get "posts") 0) }}
        {{   $posts_item := `<a href="{{ .Site.BaseURL }}post">Articles</a>` }}
        {{ end }}

I still get “Articles” at the end, even though there are posts present (I use the exact same range statement to display the most recent posts).

Got it!

        {{ $.Scratch.Set "posts_item" "Articles" }}
        {{ if (gt (where .Site.Pages "Section" "post" | len) 0) }}
        {{   $.Scratch.Set "posts_item" `<a href="` }}
        {{   $.Scratch.Add "posts_item" .Site.BaseURL }}
        {{   $.Scratch.Add "posts_item" `post">Articles</a>` }}
        {{ end }}
        <li>{{ $.Scratch.Get "posts_item" | safeHTML}}</li>

Thanks!

1 Like

One final question :slight_smile: The template now looks like

      <ul>
        {{ $.Scratch.Set "section" "Articles" }}
        {{ if (gt (where .Site.Pages "Section" "post" | len) 0) }}
        {{   $.Scratch.Set "section" `<a href="` }}
        {{   $.Scratch.Add "section" .Site.BaseURL }}
        {{   $.Scratch.Add "section" `post">Articles</a>` }}
        {{ end }}
        <li>{{ $.Scratch.Get "section" | safeHTML}}</li>
        {{ $.Scratch.Set "section" "Links" }}
        {{ if (gt (where .Site.Pages "Section" "link" | len) 0) }}
        {{   $.Scratch.Set "section" `<a href="` }}
        {{   $.Scratch.Add "section" .Site.BaseURL }}
        {{   $.Scratch.Add "section" `link">Links</a>` }}
        {{ end }}
        <li>{{ $.Scratch.Get "section" | safeHTML }}</li>
        {{ $.Scratch.Set "section" "Quotes" }}
        {{ if (gt (where .Site.Pages "Section" "quote" | len) 0) }}
        {{   $.Scratch.Set "section" `<a href="` }}
        {{   $.Scratch.Add "section" .Site.BaseURL }}
        {{   $.Scratch.Add "section" `quote">Quotes</a>` }}
        {{ end }}
        <li>{{ $.Scratch.Get "section" | safeHTML }}</li>
      </ul>

with the generated HTML becoming

      <ul>
        
        
        
        
        
        
        <li><a href="https://pfig.be/post">Articles</a></li>
        
        
        
        
        
        
        <li><a href="https://pfig.be/link">Links</a></li>
        
        
        
        
        
        
        <li><a href="https://pfig.be/quote">Quotes</a></li>
      </ul>

Surely there’s a better way to do this and I’m just being thick, right? It’s 5:30 in the UK :slight_smile:

I think what you see here is this issue:

In Hugo these extra newlines doesn’t impact the rendering, but they do look ugly. I have a HTML minifier in my build chain (Gulp task) to fix this (and other things).