在Go HTML模板中创建struct map键的语法

时间:2017-08-10 10:36:20

标签: go go-templates

我正在编写一个简单的Go程序来显示每个环境部署的服务版本的HTML表。我的程序包含以下结构:

Versions

如您所见,versionKey地图使用"1.0.0"作为字符串值的键,例如templateData

我将Environments结构体传递给HTML模板并覆盖其ServicesversionKey切片以构建HTML表格。问题是我需要为任何给定的环境和服务交集构建Versions,这样我就可以使用它来查找$environment映射中的版本并在表格单元格中输出该值。 / p>

在模板中,我可以从范围中获得$serviceversionKey变量,但我无法计算Go模板语法来创建{{$environments := .Environments}} {{$services := .Services}} {{$versions := .Versions}} {{range $service := $services}} ... {{range $environment := $environments}} ... {{index $versions ...? }} // How to create versionKey struct map key here? ... {{end}} ... {{end}} 结构。

这里是省略了标记的模板代码:

$array = array('Leanna', 'nicole', 'Lisa', 'Sarah', 'Leopard', 'Michael', 'jack', 'logan');

foreach($array as $key => $value){
    $exp_key = explode('L', $key);
    if($exp_key[0] == 'L' || $exp_key[0] == "l"){
        $arr_result[] = $value;
    }

    echo $value . "<br />";
}

1 个答案:

答案 0 :(得分:3)

仅使用模板代码,您无法使用。您需要执行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)
}

输出(在Go Playground上尝试):

EnvA - ServA version: 1.0.0

EnvB - ServA version: 1.0.2


EnvA - ServB version: 1.0.1

EnvB - ServB version: 

替代

您可以轻松地注册一个可以从给定环境和服务创建并返回类型templateData.Version()的值的函数,而不是versionKey方法。有关详细信息,请参阅Template.Funcs()。这会更复杂,但更灵活,因为这可以在其他地方重复使用。请在此处查看此示例:Golang templates (and passing funcs to template)。稍微有点变化就是将函数值作为任何其他模板数据传递,而不是将其注册为可以调用的命名函数。

另一种选择是&#34;转换&#34;将您的Versions字段放入地图地图中,例如:

Versions map[string]map[string]string

首先可以按环境索引,然后按服务索引,在模板中可以通过2 {{index}}个动作来实现。您必须检查第一个索引是否会产生任何结果。