9

I have this Go template:

{{ if and $b.Trigger $b.Trigger.Name }} 
  Name is {{ $b.Trigger.Name }}.
{{ else }}
  ...other stuff...
{{ end }}

I'm trying to get this template to do:

if b.Trigger != nil && $b.Trigger.Name != "" { ...

however it doesn't work, because as text/template godoc says, both arguments to and/or functions are evaluated.

When the $b.Trigger.Name is evaluated, it errors out because $b.Trigger can be nil. So it returns error:

template: builds.html:24:46: executing "content" at <$b.Trigger.Name>: can't evaluate field Name in type *myType

I tried refactoring this to:

{{ if and (ne $b.Trigger nil) (ne $b.Trigger.Name "") }}

and weird enough, this fails as well, it says I can't compare $b.Trigger with nil, which doesn't make sense because that field is a pointer type:

template: builds.html:24:31: executing "content" at <ne $b.Trigger nil>: error calling ne: invalid type for comparison

Any ideas?

ahmet alp balkan
  • 42,679
  • 38
  • 138
  • 214
  • Possible duplicate of [Go template and function](https://stackoverflow.com/questions/42208440/go-template-and-function). – icza Jun 16 '17 at 07:05
  • By default `if` can handle `nil` values `{{ if $b.Trigger }}`, if its `non-nil` it will get in. Then you can add nested `if` for empty string check. – jeevatkm Jun 16 '17 at 07:05
  • 1
    Or you can add your own template func please refer @icza comment. – jeevatkm Jun 16 '17 at 07:07
  • 3
    Nest your ifs. Dead simple. readable and not clever. – Volker Jun 16 '17 at 07:45

2 Answers2

5

As Volker noted above, nest the ifs:

{{if $b.Trigger}}{{if $b.Trigger.Name}}
  Name is {{ $b.Trigger.Name }}.
{{end}}{{end}}

Or, more succinctly:

{{with $b.Trigger}}{{with .Name}}
  Name is {{.}}.
{{end}}{{end}}

Unfortunately, the above won't handle else clauses. Here's one (rather ugly) possibility:

{{$bTriggerName := ""}}
{{with $b.Trigger}}{{$bTriggerName = .Name}}{{end}}
{{with $bTriggerName}}
  Name is {{.}}.
{{else}}
  ...other stuff...
{{end}}

I looked to see if gobuffalo/plush could do this more elegantly, but as of 2019-04-30 it cannot.

Chaim Leib Halbert
  • 2,194
  • 20
  • 23
0

Here explains why all arguments are evaluated in a pipeline. It is evaluated through go template functions https://golang.org/pkg/text/template/#hdr-Functions

Ming L.
  • 391
  • 2
  • 7