Golang中执行嵌套HTML模板的最佳方法

Golang中执行嵌套HTML模板的最佳方法 我是Go语言的新手,但到目前为止我非常喜欢它。我想了解解析HTML模板最有效的方法。

我有一个小型Web应用,包含一个布局模板和独立的嵌套内容模板。如果我在每个处理程序中分别解析模板,它可以正常工作。例如:

tmpl := template.Must(template.ParseFiles("templates/layout.gohtml", "templates/index.gohtml"))
tmpl.Execute(w, data)

根据我的阅读和理解,更好的做法是全局解析所有模板一次,然后按名称执行它们。例如:

var templates = template.Must(template.ParseGlob("templates/*"))   // 包内全局变量
...
err := templates.ExecuteTemplate(w, "index.gohtml", data)    // 在处理程序中

然而,这对我来说似乎不起作用。我得到一个空白页面。我猜想它没有进行嵌套。但我不确定为什么它不工作。我似乎找不到任何展示这种场景的例子。

我遗漏了什么?我应该只在本地解析它们而不必担心吗?最有效的方法是什么?

谢谢

index.gohtml:

{{define "title"}}Home{{end}}
{{define "content"}}
    <p>Do something...</p>
{{end}}

layout.gohtml: (简化版)

<!doctype html>
<html lang="en">
<head>
    <title>{{template "title" .}}</title>
</head>
<body>
    {{template "content" .}}
</body>
</html>

更多关于Golang中执行嵌套HTML模板的最佳方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

我漏掉了什么?我应该直接在本地解析它们而不必担心吗?最有效的方法是什么?

请注意,你可以在开头使用 {{define "content"}}

我最初确实尝试了你的方法。你可以这样做,但有点棘手。你必须动态地“嵌入”内容。

layout := tpl.Lookup("layout.html")
layout, _ = layout.Clone()
t := tpl.Lookup(path)
if t == nil {
	//404.html
}
_, _ = layout.AddParseTree("content", t.Tree)

head := title.Title(path)
layout.Execute(w, head)

现在我换了一种更简单的方式。在主模板中使用子模板。这样更容易维护。https://gowebstatic.tk/pages

更多关于Golang中执行嵌套HTML模板的最佳方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go中执行嵌套HTML模板时,使用template.ParseGlobtemplate.ParseFiles全局解析是正确的做法。你遇到的问题是因为模板定义和执行的逻辑需要明确指定。

当你使用templates.ExecuteTemplate(w, "index.gohtml", data)时,你是在执行名为"index.gohtml"的模板定义。但根据你的代码,index.gohtml只定义了"title""content"两个命名模板块,并没有定义完整的HTML结构。你应该执行的是"layout.gohtml",因为它包含了完整的HTML框架并嵌入了其他模板。

以下是修正后的示例:

// 全局解析所有模板
var templates = template.Must(template.ParseGlob("templates/*.gohtml"))

func handler(w http.ResponseWriter, r *http.Request) {
    // 执行布局模板,它会自动嵌入index.gohtml中定义的块
    err := templates.ExecuteTemplate(w, "layout.gohtml", data)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

如果你的布局模板名称不是"layout.gohtml",请确保传递给ExecuteTemplate的名称与文件中的{{define}}名称完全匹配。例如,如果布局文件内容如下:

{{define "base"}}
<!doctype html>
<html>
    <title>{{template "title" .}}</title>
    <body>{{template "content" .}}</body>
</html>
{{end}}

那么执行时应该使用:

templates.ExecuteTemplate(w, "base", data)

另一种常见模式是使用template.ParseFiles明确指定文件解析顺序:

var templates = template.Must(template.New("").ParseFiles(
    "templates/layout.gohtml",
    "templates/index.gohtml",
    // 其他模板文件
))

这样解析后,你可以通过ExecuteTemplate(w, "layout.gohtml", data)正确执行嵌套模板。全局解析一次模板是推荐的做法,避免了每次请求都重新解析模板的开销。

回到顶部