如何将当前年份添加到 Go 模板中?

问题描述 投票:0回答:3

在 Go 模板中,您可以检索如下字段:

template.Parse("<html><body>{{ .Title }}</body></html>")
template.Execute(w, myObject)

如何“内联”当前 UTC 年份?我想做这样的事情:

template.Parse("<html><body>The current year is {{time.Time.Now().UTC().Year()}}</body></html>")

但它返回错误:

恐慌:模板:函数“时间”未定义

go go-templates
3个回答
13
投票

您可以向模板添加功能,试试这个:

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)
    }
}

3
投票

您已经在模板中包含了

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 上的当前日期/时间是

2009-11-10 23:00:00
,这就是您看到
2009
的原因)。

根据设计理念,模板不应包含复杂逻辑。如果模板中的某些内容(或看起来)太复杂,您应该考虑在 Go 代码中计算结果,并将结果作为数据传递给执行,或者在模板中注册回调函数,并让模板操作调用该函数并插入返回值。

可以说,获取当前年份并不是一个复杂的逻辑。但Go是一种静态链接语言。您只需保证可执行二进制文件仅包含您的 Go(源)代码显式引用的包和函数。这适用于标准库的所有包(

runtime
包除外)。因此,模板文本不能仅引用和调用
time
包等包中的函数,因为不能保证在运行时可用。


0
投票

使用 std

Format
结构的
Time
方法,而无需使用该结构。它接受以下任何常量:https://pkg.go.dev/time#pkg-constants

package main

import (
    "fmt"
    "html/template"
    "net/http"
    "time"
)

func main() {
    t, _ := template.New("site").Parse(`<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>

<body>
    <footer>
        <p>&copy; {{ .Now.Format "2006" }} All Rights Reserved.</p>
    </footer>
</body>

</html>`) // handle your error in real code

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        t.Execute(w, struct{ Now time.Time }{Now: time.Now()})
    })
    fmt.Println("stopped:", http.ListenAndServe(":3333", nil))
}

注意

2006
是标准符号,
{{ .Now.Format "2007" }}
的含义不同

2007 means
2--------> Day of the Month without the leading zero
 0-------> Literal zero
  07-----> TIMEZONE https://en.wikipedia.org/wiki/UTC%E2%88%9207:00
© www.soinside.com 2019 - 2024. All rights reserved.