在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 09:12:36  来源:igfitidea点击:

Switch or if/elseif/else inside golang HTML templates

htmltemplatesgogo-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 Typedependent way.

我想以Type依赖的方式显示我的段落。

The only solution I found was based on dedicated functions like isAttachmenttesting the Typein 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 IsSomethingfunctions and the template with those {{end}}.

事实上,我有更多的类型,这让它变得更加奇怪,将带有IsSomething函数的 Go 代码和带有那些{{end}}.

What's the clean solution ? Is there some switchor if/elseif/elsesolution in go templates ? Or a completely different way to handle these cases ?

什么是干净的解决方案?go 模板中有一些switchif/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 switchfunctionality by adding custom functions to the template.FuncMap.

您可以switch通过向template.FuncMap添加自定义函数来实现功能。

In the example below I've defined a function, printPara (paratype int) stringwhich 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 .Paratypeis piped into the printparafunction. 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 FuncMaps. This pagehas some good info, as well as the first link.

请注意,在实际模板中,通过.Paratype管道传输到printpara函数中。这是在模板中传递参数的方法。请注意,添加到FuncMaps 的函数的输出参数的数量和形式是有限制的。这个页面有一些很好的信息,以及第一个链接。

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:

选择任何选项:

Playground link

游乐场链接

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.

希望有帮助,我很确定代码可以稍微清理一下,但我已经尝试接近您提供的示例代码。