如何将当前年份添加到 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 包等包中的函数,因为无法保证在运行时可用。