【问题标题】:How to declare a global variable in a template?如何在模板中声明全局变量?
【发布时间】:2020-05-10 02:40:08
【问题描述】:

我需要编写一个模板,我首先定义一些变量,然后在模板生成的内容中使用它们:

{{ if $value.Env.CADDY_URL }}
    {{ $url := $value.Env.CADDY_URL }}
{{ else }}
    {{ $url := printf "http://%s.example.info" $value.Name }}
{{ end }}

{{/* more template */}}
{{/* and here I would like to use $url defined above */}}
{{ $url }}

我得到了错误

undefined variable "$url"

阅读documentation,我明白了

变量的作用域扩展到声明它的控制结构(“if”、“with”或“range”)的“结束”操作,如果没有这样的控制,则扩展到模板的末尾结构。

这是否意味着没有全局(或整个模板的范围)变量?或者有没有办法定义$url,以便以后在模板中重复使用?

【问题讨论】:

  • 在 if 块之前使用 {{ $url := "" }} 声明它,然后在 if 块中使用 {{ $url = value }} 设置它。

标签: go go-templates


【解决方案1】:

变量是有范围的。您在 {{if}}{{else}} 块内创建 $url 变量,因此它们在这些块之外不可见。

{{if}}之前创建变量,并使用赋值=代替声明:=

{{$url := ""}}
{{ if . }}
    {{ $url = "http://true.com" }}
{{ else }}
    {{ $url = "http://false.com" }}
{{ end }}

{{ $url }}

测试它:

t := template.Must(template.New("").Parse(src))

fmt.Println(t.Execute(os.Stdout, true))
fmt.Println(t.Execute(os.Stdout, false))

输出(在Go Playground 上试试):

http://true.com<nil>
http://false.com<nil>

注意: Go 1.11 中添加了使用赋值修改模板变量,因此您需要使用 Go 1.11 或更高版本构建您的应用程序。如果您使用的是旧版本,则无法修改模板变量的值。

编辑:我发现了一个重复:How do I assign variables within a conditional

您可以在早期版本中模仿“可变模板变量”,例如,请参阅此问题:In a Go template range loop, are variables declared outside the loop reset on each iteration?

【讨论】:

  • 谢谢。我尝试了这个,然后在分配新值的行上获得unexpected "=" in operand(在我上面的示例中,这将是(根据您的示例修改)行{{ $url = $value.Env.CADDY_URL }}(在最顶部添加{{ $url := "" }}之后)跨度>
  • 我想知道这是否与github.com/golang/go/issues/10608无关。可能是这种情况,因为我使用的程序已经有 4 年历史了,而且在模板中覆盖变量的能力似乎是新的。 编辑:是的,这就是原因:github.com/jwilder/docker-gen/issues/299
  • 是的,Go 1.11 中添加了使用赋值修改变量,参见release notes
猜你喜欢
  • 2014-10-30
  • 2019-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多