Conditionally assign values to variables

I was struggling with conditional variables in templates for a while, especially when checking for properties that may not exist. Other than writing giants blocks of if else conditions I also kept running into can't evaluate field context in type errors. Not being super familiar with Go I wasn’t getting very far, and searching was not helpful.

I finally figured it out, and hopefully this post helps others. In my case I was trying to write a partial that could output links from multiple sources. I wanted to default to Permalink but fall back to URL in the case of menu items defined in config. For these menu items Permalink wasn’t defined and kept throwing the can't evaluate... error.

What failed:

{{ $url := "EMPTY" }}
{{ if .Permalink }}
  {{ $url = .Permalink }}
{{ else }}
  {{ $url = .URL }}
{{ end }}

<a href={{ $url | safeURL }}>My link</a>

What ended up working was double negation:

{{ $url := "EMPTY" }}
{{ $hasPermalink := not (not .Permalink) }}
{{ $url = cond $hasPermalink .Permalink .URL }}

<a href={{ $url | safeURL }}>My link</a>

Whoop! Happy Coding!

  • Admins, if this is a duplicate, or has been mentioned somewhere else I was unable to find it. Feel free to delete.
1 Like
{{ $url := .URL }}
{{ with .Permalink }}
  {{ $url = . }}
{{ end }}
<a href={{ $url | safeURL }}>My link</a>

You might want to read up the documentation about conditionals.

“properties that might not exist” = with

2 Likes

I tried with but it doesn’t work for variables on the root of the data object. So if .Permalink is not defined, like in menu entries, it will complain.

<.Permalink>: can't evaluate field Permalink in type *navigation.MenuEntry

Looking at this again, it looks like my own solution also fails when I pass context outside of a dictionary. So my own solution, at this juncture, is a bust :sob:


I ended up creating 2 partials for my navigation <ul>s, one for regular link lists, like section menus, and one for the config.yaml menus. Only the ul is duplicated into 2 partials, one of which passes .URL from menuEntry as link and the other passes .Permalink as link.

It’s a little frustrating, but I can’t find any other way to get past non-existent .Permalink on menuEntry.

Have you tried isset?

For instance

{{ $url := "EMPTY" }}
{{ if isset . "Permalink" }}
  {{ $url = .Permalink }}
{{ else if isset . "URL" }}
  {{ $url = .URL }}
{{ end }}

I haven’t tested; just thinking out lout.