Golang模板顺序

Golang template order

有没有办法让模板顺序无关紧要。

这是我的代码:

var overallTemplates = []string{
    "templates/analytics.html",
    "templates/header.html",
    "templates/footer.html"}

func HomeHandler(w http.ResponseWriter, r *http.Request) {
    render(w,
        append([]string{"templates/home.html"}, overallTemplates...),
        nil)
}

func render(w http.ResponseWriter, files []string, data interface{}) {
    tmpl := template.Must(template.ParseFiles(files...))
    err := tmpl.Execute(w, data)

    if err != nil {
        fmt.Printf("Couldn't load template: %v\n", err)
    }
}

它有效,但如果我将 overallTemplates 的顺序更改为:

var overallTemplates = []string{
    "templates/header.html",
    "templates/footer.html",
    "templates/analytics.html"}

我得到一个空白页,因为 analytics.html 内容类似于 {{define "analytics"}}...{{end}},它被 footer.html 称为 {{define "footer"}}{{template "analytics"}} ...{{end}}

template.ParseFiles() 记录:

The returned template's name will have the (base) name and (parsed) contents of the first file.

因此,在您的第一个示例中,您的模板指定了 "templates/analytics.html",因为这是您传递的第一个模板,当您更改顺序时,模板将指定 "templates/header.html"

如果您使用 Template.Execute() 执行模板,这些是要执行的(默认)模板。

相反,您应该使用 Template.ExecuteTemplate() 并明确指定您要执行 "templates/analytics.html",其名称将是 analytics,因此传递:

err := tmpl.ExecuteTemplate(w, "analytics", data)

这样一来,您将模板传递给 template.ParseFiles() 的顺序就无关紧要了。

友情提示:不要在处理程序中解析您的模板:它很慢。解析它们一次,在应用程序启动时,将它们存储起来,例如在包变量中,并在处理程序中执行它们。有关详细信息,请参阅 It takes too much time when using "template" package to generate a dynamic web page to client in Golang

另见相关问题: