Is there a friendlier version of isset?

Is there an alternative to isset that doesn’t stop processing the template when it hits an undefined variable? Trying to do defensive coding in a theme (if a value’s not supplied, do something reasonable instead of breaking the processing) gets unwieldy with a much of a hierarchy.

{{ if isset .Site.Params "foo" }}
	{{ if isset .Site.Params.foo "bar" }}
		<p>blah {{ .Permalink }} blah {{ .Title }} blah {{.Site.Params.foo.bar}}"</p>
	{{ else }}
		<p>meh {{ .RSSLink }}</p>
	{{ end }}
{{ else }}
		<p>meh {{ .RSSLink }}</p>
{{ end }}

I can be clever and use and (isset ...) (isset ...), but it would be a lot cleaner to just have isset not throw an error when hitting undefined values and just return false.

{{ if isset .Site.Params.foo.bar }}
	<p>blah {{ .Permalink }} blah {{ .Title }} blah {{.Site.Params.foo.bar}}"</p>
{{ else }}
	<p>meh {{ .RSSLink }}</p>
{{ end }}

I don’t think that with is a good alternative here because the general case can use other variables beside the one being tested. And something like if and (isset .Site.Params.one.path) (isset .Site.Params.two.blerg)) just keeps piling on the complexity.

1 Like

I haven’t tested the snipped below but wouldn’t it be possible to boil it down to something like this?

{{ with .Site.Params.foo.bar }}
	&lt;p&gt;blah {{ $.Permalink }} blah {{ $.Title }} blah {{ . }}"&lt;/p&gt;
{{ else }}
	&lt;p&gt;meh {{ $.RSSLink }}&lt;/p&gt;
{{ end }}

I don’t think so. The variables like .Title aren’t in the scope of . so they throw an error.

There’s another function, echoParam, that calls returnWhenSet that sort of does something similar. You can put in pretty much anything and it won’t stop the template if the variable’s not defined.

{{echoParam .Site.Params "foo.bar.joy"}}

But I can’t get that to work in an if statement:

{{ if not (eq "" (echoParam .Site.Params.foo "bar")) }}

That’s why I prepended a $.

My bad, it does work and is easy to read. I still have the concern with multiple values, that gets convoluted.

{{ with .Site.Params.one.path }}
	{{ with $.Site.Params.two.path }}
		<p>one {{$.Site.Params.one.path}} two {{.}} stuff {{$.Title}}
	{{ else }}
		<p>meh {{$.RSSLink}}</p>
	{{ end }}
{{ else }}
	<p>meh {{$.RSSLink}}</p>
{{ end }}

It’s all possible to write, it’d just be easier if isset didn’t stop the template processing.

If you’ve two params it is still readable:

{{ if .Site.Params.one.path | and .Site.Params.two.path }}
  &lt;p&gt;one {{ .Site.Params.one.path}} two {{ .Site.Params.two.path }} stuff {{$.Title}}
{{ else }}
  &lt;p&gt;meh {{$.RSSLink}}&lt;/p&gt;
{{ end }}
1 Like

That’s closer to what I’m after and works most all of the time.

It still breaks the template if the user makes a mistake in the config:

[params]
  one = "something"

I know that at some point you have to let the user be punished for mistakes and that’s a bad thing to do to a configuration entry.

I’d just like to push this one a bit further.

{{ if and (default .Site.Params.one.path) (default .Site.Params.two.path) }}

Seems to work. I’ll keep testing.

The default approach looks interesting.

Just noticed that with breaks if the config is bad, too.