如何将当前年份添加到 Go 模板中?
How do you add the current year to a Go template?
在 Go 模板中,您可以像这样检索字段:
template.Parse("<html><body>{{ .Title }}</body></html>")
template.Execute(w, myObject)
您 "inline" 当前的 UTC 年份如何?我想做这样的事情:
template.Parse("<html><body>The current year is {{time.Time.Now().UTC().Year()}}</body></html>")
但是returns错误:
panic: template: function "time" not defined
你可以给模板添加功能,试试这个:
package main
import (
"html/template"
"log"
"os"
"time"
)
func main() {
funcMap := template.FuncMap{
"now": time.Now,
}
templateText := "<html><body>The current year is {{now.UTC.Year}}</body></html>"
tmpl, err := template.New("titleTest").Funcs(funcMap).Parse(templateText)
if err != nil {
log.Fatalf("parsing: %s", err)
}
// Run the template to verify the output.
err = tmpl.Execute(os.Stdout, nil)
if err != nil {
log.Fatalf("execution: %s", err)
}
}
您已经在模板中包含 Title
。它如何最终出现在模板中?您将它作为参数传递给 Template.Execute()
。这(不出所料)也适用于当年。
与为此注册一个函数相比,这是一个更好、更简单的解决方案。这就是它的样子:
t := template.Must(template.New("").Parse(
"<html><body>{{ .Title }}; Year: {{.Year}}</body></html>"))
myObject := struct {
Title string
Year int
}{"Test Title", time.Now().UTC().Year()}
if err := t.Execute(os.Stdout, myObject); err != nil {
fmt.Println(err)
}
输出(在 Go Playground 上尝试):
<html><body>Test Title; Year: 2009</body></html>
(注意:Go Playground 上的当前 date/time 是 2009-11-10 23:00:00
,这就是您看到 2009
的原因)。
根据设计理念,模板不应包含复杂 逻辑。如果模板中的某些东西(或看起来)太复杂,您应该考虑在 Go 代码中计算结果并将结果作为数据传递给执行,或者在模板中注册回调函数并让模板操作调用该函数并插入return 值。
可以说获取当前年份并不是一个复杂的逻辑。但是 Go 是一种静态链接的语言。您只能保证可执行二进制文件将仅包含您的 Go(源)代码明确引用的包和函数。这适用于标准库的所有包(runtime
包除外)。因此,模板文本不能仅引用和调用 time
包等包中的函数,因为无法保证在运行时可用。
在 Go 模板中,您可以像这样检索字段:
template.Parse("<html><body>{{ .Title }}</body></html>")
template.Execute(w, myObject)
您 "inline" 当前的 UTC 年份如何?我想做这样的事情:
template.Parse("<html><body>The current year is {{time.Time.Now().UTC().Year()}}</body></html>")
但是returns错误:
panic: template: function "time" not defined
你可以给模板添加功能,试试这个:
package main
import (
"html/template"
"log"
"os"
"time"
)
func main() {
funcMap := template.FuncMap{
"now": time.Now,
}
templateText := "<html><body>The current year is {{now.UTC.Year}}</body></html>"
tmpl, err := template.New("titleTest").Funcs(funcMap).Parse(templateText)
if err != nil {
log.Fatalf("parsing: %s", err)
}
// Run the template to verify the output.
err = tmpl.Execute(os.Stdout, nil)
if err != nil {
log.Fatalf("execution: %s", err)
}
}
您已经在模板中包含 Title
。它如何最终出现在模板中?您将它作为参数传递给 Template.Execute()
。这(不出所料)也适用于当年。
与为此注册一个函数相比,这是一个更好、更简单的解决方案。这就是它的样子:
t := template.Must(template.New("").Parse(
"<html><body>{{ .Title }}; Year: {{.Year}}</body></html>"))
myObject := struct {
Title string
Year int
}{"Test Title", time.Now().UTC().Year()}
if err := t.Execute(os.Stdout, myObject); err != nil {
fmt.Println(err)
}
输出(在 Go Playground 上尝试):
<html><body>Test Title; Year: 2009</body></html>
(注意:Go Playground 上的当前 date/time 是 2009-11-10 23:00:00
,这就是您看到 2009
的原因)。
根据设计理念,模板不应包含复杂 逻辑。如果模板中的某些东西(或看起来)太复杂,您应该考虑在 Go 代码中计算结果并将结果作为数据传递给执行,或者在模板中注册回调函数并让模板操作调用该函数并插入return 值。
可以说获取当前年份并不是一个复杂的逻辑。但是 Go 是一种静态链接的语言。您只能保证可执行二进制文件将仅包含您的 Go(源)代码明确引用的包和函数。这适用于标准库的所有包(runtime
包除外)。因此,模板文本不能仅引用和调用 time
包等包中的函数,因为无法保证在运行时可用。