首页 > 解决方案 > 使用 go template 生成 go 模板

问题描述

我想生成类似{{ .Values.something }}使用 go 模板的东西。

但是想不通我的模板应该是什么样子,比如我想到了这样的模板

`"{{.Values."{{ .Value }}"}}"`

并针对这个结构执行它

type values struct {
    Value string
}

但它没有用,我也尝试了其他一些组合,但没有运气。有人可以帮我弄清楚如何{{ .Values.something }}从 go 模板中获取此输出。

标签: gogo-templates

解决方案


一、不改变分界线

你不能将一个{{ }}动作嵌入到另一个{{ }}动作中,这就是你尝试过的。由于模板中的{{}}文字很特殊(它们是默认分隔符),因此您必须使用操作将它们输出为文字,例如

{{ "{{" }}

{{ "}}" }}

所以一个可行的解决方案:

t := template.Must(template.New("").Parse(`{{"{{"}} .Values.{{.Value}} {{"}}"}}`))

buf := &bytes.Buffer{}

params := map[string]interface{}{
    "Value": "Something",
}

if err := t.Execute(buf, params); err != nil {
    panic(err)
}

fmt.Println(buf.String())

这个输出(在Go Playground上试试):

{{ .Values.Something }}

当然,您也可以使用此模板输出{{.Values使用一个操作:

{{"{{.Values."}}{{.Value}}{{"}}"}}

在Go Playground上尝试一下。

您也可以使用print内置模板函数一步完成所有这些操作:

{{ print "{{.Values." .Value "}}" }}

在Go Playground上试试这个。

二、更改默认分隔符

上面所有的模板功夫都是必需的,因为我们使用模板来生成一个模板,这两个模板都使用了相同的分隔符。

如果我们改变生成器模板的分隔符,我们的任务就会变得简单得多。可以使用该Template.Delims()方法更改分隔符。

因此,例如,如果我们将左右分隔符从 ( {{, }}) 更改为 ( <<, >>),那么序列{{}}不再特殊,它可以在模板中使用,它们将按原样输出。

因此,以下简单模板也可以满足您的要求:

{{ .Values.<<.Value>> }}

使用它来更改默认分隔符的示例:

t := template.Must(template.New("").
    Delims("<<", ">>").
    Parse(`{{ .Values.<<.Value>> }}`))

在Go Playground上试试这个。


推荐阅读