英文:
How to have short circuit with and/or in text/template
问题
我有这个Go模板:
{{ if and $b.Trigger $b.Trigger.Name }}
Name is {{ $b.Trigger.Name }}.
{{ else }}
...其他内容...
{{ end }}
我试图让这个模板实现以下功能:
if b.Trigger != nil && $b.Trigger.Name != "" { ...
然而它不起作用,因为根据text/template godoc所说,and/or函数的两个参数都会被求值。
当求值$b.Trigger.Name
时,它会出错,因为$b.Trigger
可能为nil。所以它返回错误:
template: builds.html:24:46: 执行“content”时出错,位于<$b.Trigger.Name>:无法在类型*myType中评估字段Name
我尝试重构为:
{{ if and (ne $b.Trigger nil) (ne $b.Trigger.Name "") }}
但奇怪的是,这也失败了,它说我不能将$b.Trigger
与nil进行比较,这是没有意义的,因为该字段是一个指针类型:
template: builds.html:24:31: 执行“content”时出错,位于<ne $b.Trigger nil>:调用ne时出错:比较的类型无效
有什么想法吗?
英文:
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?
答案1
得分: 5
如Volker在上面提到的,嵌套if语句:
{{if $b.Trigger}}{{if $b.Trigger.Name}}
名称是{{ $b.Trigger.Name }}。
{{end}}{{end}}
或者更简洁地:
{{with $b.Trigger}}{{with .Name}}
名称是{{.}}。
{{end}}{{end}}
不幸的是,上述方法无法处理else子句。下面是一个(相当丑陋的)可能性:
{{$bTriggerName := ""}}
{{with $b.Trigger}}{{$bTriggerName = .Name}}{{end}}
{{with $bTriggerName}}
名称是{{.}}。
{{else}}
...其他内容...
{{end}}
我查看了gobuffalo/plush是否可以更优雅地实现这一点,但截至2019-04-30,它无法做到。
英文:
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.
答案2
得分: 0
这里解释了为什么在管道中会评估所有的参数。它是通过Go模板函数进行评估的。
https://golang.org/pkg/text/template/#hdr-Functions
英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论