在 golang HTML 模板中切换或 if/elseif/else
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16985469/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Switch or if/elseif/else inside golang HTML templates
提问by Denys Séguret
I have this struct :
我有这个结构:
const (
paragraph_hypothesis = 1<<iota
paragraph_attachment = 1<<iota
paragraph_menu = 1<<iota
)
type Paragraph struct {
Type int // paragraph_hypothesis or paragraph_attachment or paragraph_menu
}
I want to display my paragraphs in a Type
dependent way.
我想以Type
依赖的方式显示我的段落。
The only solution I found was based on dedicated functions like isAttachment
testing the Type
in Go and nested {{if}}
:
我找到的唯一解决方案是基于专用功能,例如在 Go 中isAttachment
测试Type
和嵌套{{if}}
:
{{range .Paragraphs}}
{{if .IsAttachment}}
-- attachement presentation code --
{{else}}{{if .IsMenu}}
-- menu --
{{else}}
-- default code --
{{end}}{{end}}
{{end}}
In fact I have more types, which makes it even weirder, cluttering both the Go code with IsSomething
functions and the template with those {{end}}
.
事实上,我有更多的类型,这让它变得更加奇怪,将带有IsSomething
函数的 Go 代码和带有那些{{end}}
.
What's the clean solution ? Is there some switch
or if/elseif/else
solution in go templates ? Or a completely different way to handle these cases ?
什么是干净的解决方案?go 模板中有一些switch
或if/elseif/else
解决方案吗?或者用一种完全不同的方式来处理这些情况?
采纳答案by Florian Margaine
Templates are logic-less. They're not supposed to have this kind of logic. The maximum logic you can have is a bunch of if
.
模板是无逻辑的。他们不应该有这种逻辑。您可以拥有的最大逻辑是一堆if
.
In such a case, you're supposed to do it like this:
在这种情况下,你应该这样做:
{{if .IsAttachment}}
-- attachment presentation code --
{{end}}
{{if .IsMenu}}
-- menu --
{{end}}
{{if .IsDefault}}
-- default code --
{{end}}
回答by mcfedr
Yes, you can use {{else if .IsMenu}}
是的,你可以使用 {{else if .IsMenu}}
回答by Intermernet
You can achieve switch
functionality by adding custom functions to the template.FuncMap.
您可以switch
通过向template.FuncMap添加自定义函数来实现功能。
In the example below I've defined a function, printPara (paratype int) string
which takes one of your defined paragraph types and changes it's output accordingly.
在下面的示例中,我定义了一个函数,printPara (paratype int) string
它采用您定义的段落类型之一并相应地更改其输出。
Please note that, in the actual template, the .Paratype
is piped into the printpara
function. This is how to pass parameters in templates. Please note that there are restrictions on the number and form of the output parameters for functions added to FuncMap
s. This pagehas some good info, as well as the first link.
请注意,在实际模板中,通过.Paratype
管道传输到printpara
函数中。这是在模板中传递参数的方法。请注意,添加到FuncMap
s 的函数的输出参数的数量和形式是有限制的。这个页面有一些很好的信息,以及第一个链接。
package main
import (
"fmt"
"os"
"html/template"
)
func main() {
const (
paragraph_hypothesis = 1 << iota
paragraph_attachment = 1 << iota
paragraph_menu = 1 << iota
)
const text = "{{.Paratype | printpara}}\n" // A simple test template
type Paragraph struct {
Paratype int
}
var paralist = []*Paragraph{
&Paragraph{paragraph_hypothesis},
&Paragraph{paragraph_attachment},
&Paragraph{paragraph_menu},
}
t := template.New("testparagraphs")
printPara := func(paratype int) string {
text := ""
switch paratype {
case paragraph_hypothesis:
text = "This is a hypothesis\n"
case paragraph_attachment:
text = "This is an attachment\n"
case paragraph_menu:
text = "Menu\n1:\n2:\n3:\n\nPick any option:\n"
}
return text
}
template.Must(t.Funcs(template.FuncMap{"printpara": printPara}).Parse(text))
for _, p := range paralist {
err := t.Execute(os.Stdout, p)
if err != nil {
fmt.Println("executing template:", err)
}
}
}
Produces:
产生:
This is a hypothesis
This is an attachment
Menu
1:
2:
3:Pick any option:
这是一个假设
这是附件
菜单
1:
2:
3:选择任何选项:
Hope that helps, I'm pretty sure the code could be cleaned up a bit, but I've tried to stay close to the example code you provided.
希望有帮助,我很确定代码可以稍微清理一下,但我已经尝试接近您提供的示例代码。