How to have short circuit with and/or in text/template
Asked Answered
L

2

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?

Lettered answered 16/6, 2017 at 6:39 Comment(4)
Possible duplicate of Go template and function.Indefinite
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.Chatterbox
Or you can add your own template func please refer @Indefinite comment.Chatterbox
Nest your ifs. Dead simple. readable and not clever.Lotte
S
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.

Selfreliant answered 1/5, 2019 at 4:6 Comment(0)
S
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

Sexpot answered 1/6, 2021 at 22:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.