【问题标题】:template.Execute() vs. template.ExecuteTemplate()template.Execute() 与 template.ExecuteTemplate()
【发布时间】:2022-01-27 01:27:44
【问题描述】:

以下代码产生错误:

panic: template: body: "body" is an incomplete or empty template
//go:embed resources/*
var res embed.FS

func main() {
    root, _ := fs.Sub(res, "resources")
    t, err := template.New("body").ParseFS(root, "home.html")
    assert(err)
    assert(t.Execute(os.Stdout, nil))
}

模板文件resources/home.html很简单:

{{define "body"}}
Hello World!
{{end}}

如果我把main()的最后一行改成t.ExecuteTemplate(os.Stdout, "body", nil),问题就消失了。

从库源代码中,我注意到错误是因为:

func (t *Template) execute(wr io.Writer, data interface{}) (err error) {
    ... ...
    if t.Tree == nil || t.Root == nil {
        state.errorf("%q is an incomplete or empty template", t.Name())
    }
    ... ...
}

但是为什么t.Treet.Rootnil?我的 go 版本是:

go version go1.17.5 linux/amd64

【问题讨论】:

  • “当然,除了整个程序结构可能会有所不同。” -- 模板文件的基本名称是否改变了?前一个项目是否有一个名为 body 的文件,然后在新项目中将其重命名为其他名称,例如 body.html?例如go.dev/play/p/AyUSOtyZZSP
  • 不,它们没有名为 body 或 body.html 等的文件。模板的路径是 templates/login.htmltemplates/home.html(在两个项目中)。最显着的结构差异是旧项目有多个包(即代码在不同的子文件夹中,而新项目没有。
  • 如果文件名和相对位置没有改变,那么代码肯定已经改变,要么是 Go 代码,要么是模板代码。如果您仍然想声称代码没有更改,那么您需要提供一些证据,即minimal reproducible example,否则问题中没有任何内容支持您声称相同代码的两个相同版本行为不同的说法.
  • 我明白,但提供一个最小的可重现示例可能并不容易。或者,我尝试了解 t.Root 和 t.Tree 设置的位置和时间,并尝试追踪未设置的原因。
  • @mkopriva 我设法用一个非常简单的程序重现了这个问题

标签: go go-templates


【解决方案1】:

我发现了问题。 VSCode 自动为我导入text/template。此包将无法正确解析 {{define "..."}} 指令。

使用html/template 工作正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-11
    • 2015-06-18
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    • 2015-12-10
    相关资源
    最近更新 更多