20

In my template, I would like to include some default meta tags (90% of the time). However, when a specific property is set, I would like to show a different set of text.

I know I can set an anonymous struct and set a property with either "default" or "some-x". However, this means, I need to add an anonymous struct to 90% of my handlers that just currently pass nil.

Is there way to do something like

{{if eq . nil}} 
   // default meta tag
{{else if eq .MetaValue "some-x"}} 
   //other
{{end}}

If I try something like my above code, it compiles but doesn't do what I want. Appreciate any suggestions on how to handle it properly without adding a lot of boiler plate.

Thanks!

Yves M.
  • 29,855
  • 23
  • 108
  • 144
Ecognium
  • 2,046
  • 1
  • 19
  • 35

3 Answers3

24
{{if not .}}
   output when . is nil or otherwise empty including
     false, 0, and any array, slice, map, or string of length zero
{{else if eq .MetaValue "some-x"}}
       // some-x case
{{else}} 
       // other case
{{end}}
Charlie Tumahai
  • 113,709
  • 12
  • 249
  • 242
  • Thanks, Bravada. One related question: is it possible to check the existence of a `defined template`. If I have partials defined in each template (say "title") and I want to check the existence of it, there is no way to do that I presume? i.e., the pipeline can only come from the go handler? – Ecognium Sep 25 '15 at 05:36
  • There's no point in checking for the existence of the template. If you have {{template "title"}} in a template, then Execute will return an error if {{define "title"}}{{end}} is missing from the set of templates. – Charlie Tumahai Sep 25 '15 at 05:56
  • Got it. I was trying to do some default html insertions in case a template was not defined (like each partial may have an additional footer). If it is not defined, I wanted to skip it and if it is there, include it. I ended up just making every page provide the same template definitions but blank values where appropriate. – Ecognium Sep 25 '15 at 07:12
10

If you want to ensure you're only checking against nil and not 0, false, the empty string, or any other falsey type, you can use the kindIs function to accomplish this.

{{ if kindIs "invalid" . }} 
   // only if variable is literally nil. falsey values will fallthrough.
{{ else if eq .MetaValue "some-x" }} 
   // other
{{ else }}
   // final case, if any
{{ end }}
Technetium
  • 5,902
  • 2
  • 43
  • 54
5

I've been recently facing an issue with identifying nil vs 0 values in a Helm Chart (which uses Go templates, including sprig) and haven't found any solutions posted, so I thought I'd add mine here.

I came up with a kind of ugly solution which is to quote the value and then check for a string that matches "<nil>" (with quotes, so you'd actually be checking (quote .Values.thing | eq "\"<nil>\"")). This allows differentiating tests against empty values vs defined 0 values. In my case, I was trying to build a config file where some default options were non-0, so when 0 was explicitly set, I wanted to know that 0 was set instead of just omitted.

Hopefully this can be a help to someone else.

It would be nice to have a better way to do this, but so far I haven't found anything that doesn't require creating and adding my own template functions.

Dan
  • 51
  • 1
  • 2
  • 1
    I didn't see quote function in golang templates, so with your idea, I checked for `if html .Page.Thing.Stationary | eq "<nil>"` and that worked! – matt Jun 02 '18 at 03:50
  • Yeah that works too. The quote function exists in the [sprig](https://github.com/Masterminds/sprig) template library. – Dan Jun 04 '18 at 21:15
  • This no longer works in later versions of tiller (verified against 2.14.0). It now renders `(quote nil)` as an empty string (without quotes!). What still works is `(typeOf nil)`, which renders as `` (without quotes), and works back at least in tiller 2.8.2, and continues to work up to 2.14.0. – Jan Dubois Aug 02 '19 at 00:27