在golang HTML模板中切换或if/elseif/else

Den*_*ret 33 html templates go go-templates

我有这个结构:

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
}
Run Code Online (Sandbox Code Playgroud)

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

我找到的唯一解决方案是基于专用函数,如isAttachment测试TypeGo和嵌套{{if}}:

{{range .Paragraphs}}
    {{if .IsAttachment}}
        -- attachement presentation code  --
    {{else}}{{if .IsMenu}}
        -- menu --
    {{else}}
        -- default code --
    {{end}}{{end}}
{{end}}
Run Code Online (Sandbox Code Playgroud)

事实上,我有更多类型,这使得它甚至更奇怪,使用IsSomething函数和带有函数的模板混乱{{end}}.

什么是干净的解决方案?go模板中是否有一些switchif/elseif/else解决方案?还是以完全不同的方式处理这些案件?

Flo*_*ine 31

模板是无逻辑的.他们不应该有这种逻辑.你可以拥有的最大逻辑是一堆if.

在这种情况下,你应该这样做:

{{if .IsAttachment}}
    -- attachment presentation code --
{{end}}

{{if .IsMenu}}
    -- menu --
{{end}}

{{if .IsDefault}}
    -- default code --
{{end}}
Run Code Online (Sandbox Code Playgroud)

  • 实际上,问题始于`IsDefault`的定义.最后,您首先要复制模板和Go代码中必须存在的所有表示逻辑,然后在Go中使用大量详细代码来支持模板,模板不会带来任何附加值. (3认同)
  • 有'else`和`else if` (3认同)
  • 替换:“文本/模板不应该有这种逻辑。” 与:“文本/模板不支持更复杂的逻辑。” (2认同)

mcf*_*edr 12

是的,您可以使用 {{else if .IsMenu}}

  • 这有效。也许这是模板的新功能。谢谢 (4认同)

Int*_*net 7

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

在下面的示例中,我定义了一个函数,printPara (paratype int) string它接受一个已定义的段落类型并相应地更改其输出.

请注意,在实际模板中,.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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

生产:

这是一个假设

这是一个附件

菜单
1:
2:
3:

选择任何选项:

游乐场链接

希望有所帮助,我很确定代码可以清理一下,但我试图接近你提供的示例代码.

  • 这很有趣,但在您的解决方案中,HTML 中的段落渲染是在 Go 中进行的(在 `printPara` 中)。那么使用模板似乎没有任何意义。 (3认同)
  • @Intermernet我认为两者都破坏了,我正在寻找这样的东西:http://pastebin.com/QSz0vAxk (2认同)