在Go HTML模板中创建结构映射键的语法
我正在编写一个简单的Go程序来显示每个环境中部署的服务版本的HTML表。我的程序包含以下结构:在Go HTML模板中创建结构映射键的语法,go,go-templates,Go,Go Templates,我正在编写一个简单的Go程序来显示每个环境中部署的服务版本的HTML表。我的程序包含以下结构: type versionKey struct { Environment string Service string } type templateData struct { Environments []string Services []string Versions map[versionKey]string } 如您所见,Ve
type versionKey struct {
Environment string
Service string
}
type templateData struct {
Environments []string
Services []string
Versions map[versionKey]string
}
如您所见,Versions
映射使用versionKey
作为字符串值的键,例如“1.0.0”
我将templateData
struct传递给一个HTML模板,并在其环境
和服务
切片上进行排列,以构建HTML表。问题是,我需要为环境和服务的任何给定交叉点构造一个versionKey
,以便使用它从Versions
映射中查找版本,并在表格单元格中输出该值
在模板中,我有$environment
和$service
变量可供选择,但我无法计算Go模板语法来创建versionKey
结构
以下是省略标记的模板代码:
{{$environments := .Environments}}
{{$services := .Services}}
{{$versions := .Versions}}
{{range $service := $services}}
...
{{range $environment := $environments}}
...
{{index $versions ...? }} // How to create versionKey struct map key here?
...
{{end}}
...
{{end}}
仅使用模板代码,您不能。要做到这一点,您需要执行Go代码提供某种支持。根据设计理念,模板不应包含复杂的逻辑。您可能会争论这是否复杂,但模板语法不支持这一点 最简单的解决方案是将
Version()
方法添加到templateData
结构中,该结构将简单地返回给定环境和服务的版本:
func (t *templateData) Version(environment, service string) string {
return t.Versions[versionKey{
Environment: environment,
Service: service,
}]
}
从模板中使用此选项:
{{range $service := $services -}}
{{range $environment := $environments}}
{{$environment}} - {{$service}} version: {{$.Version $environment $service}}
{{end}}
{{end}}
测试它:
t := template.Must(template.New("").Parse(templ))
td := &templateData{
Environments: []string{"EnvA", "EnvB"},
Services: []string{"ServA", "ServB"},
Versions: map[versionKey]string{
{"EnvA", "ServA"}: "1.0.0",
{"EnvA", "ServB"}: "1.0.1",
{"EnvB", "ServA"}: "1.0.2",
},
}
if err := t.Execute(os.Stdout, td); err != nil {
panic(err)
}
输出(在上尝试):
选择
代替templateData.Version()
方法,您可以轻松注册一个函数,该函数可以从给定的环境和服务创建并返回versionKey
类型的值。有关详细信息,请参阅。这将更复杂,但更灵活,因为它可以在其他地方重用。请参见此处的示例:。这种方法的一个微小变化是将函数值作为任何其他模板数据传递,而不是将其注册为可调用的命名函数
另一种选择是将版本
字段“转换”为地图地图,例如:
Versions map[string]map[string]string
首先可以按环境索引,然后按服务索引,在模板中可以通过2个
{{index}}
操作来实现。不过,您必须检查第一次索引是否会产生任何结果。这是一个极好的答案,非常感谢。出于兴趣,为什么要为templateData
使用指针?@JohnTopley(指针和非指针接收器)在这个简单的示例中都可以使用。我使用指针接收器完全是出于习惯,如果这个例子演变成一个更复杂的例子,其中方法也需要改变/修改接收器,我不必返回并将接收器更改为指针接收器。
Versions map[string]map[string]string