我是Golang的新手,我正在尝试使用模板文件和良好的缓存系统来设置一个Web项目。
我有layout.html
,1.html
,2.html
。
所以我在渲染函数中加载layout.html
:
err := templates.ExecuteTemplate(w, "layout.html", nil)
layout.html
看起来像这样:
...
<body>{{template "content" .}}</body>
...
1.html
{{define "content"}}This is the first page.{{end}}
2.html
{{define "content"}}This is the second page.{{end}}
我无法使用
var templates = template.Must(template.ParseFiles(
"layout.html",
"1.html",
"2.html"))
由于2.html
覆盖1.html
。
所以我有两种方式:
templates["1"] = template.Must(template.ParseFiles("layout.html","1.html"))
templates["2"] = template.Must(template.ParseFiles("layout.html","2.html"))
有没有新方法或更好的方法来做到这一点?
答案 0 :(得分:2)
在我的项目中,我使用了这个辅助函数:
func executeTemplate(tmpls *template.Template, tmplName string, w io.Writer, data interface{}) error {
var err error
layout := tmpls.Lookup("layout.html")
if layout == nil {
return errNoLayout
}
layout, err = layout.Clone()
if err != nil {
return err
}
t := tmpls.Lookup(tmplName)
if t == nil {
return errNoTemplate
}
_, err = layout.AddParseTree("content", t.Tree)
if err != nil {
return err
}
return layout.Execute(w, data)
}
tmpls
是包含所有已解析模板作为“子模板”的模板,例如来自ParseFiles
。 layout.html
看起来像这样:
<main class="container">
{{template "content" .}}
</main>
虽然其他模板是这样的:
<h1>Welcome</h1>
请注意,内容模板不需要以{{define "content"}}
开头。
答案 1 :(得分:1)
包级映射或变量都是缓存已编译模板的好方法。上面#2中的代码没问题。以下是如何使用包级变量:
var t1 = template.Must(template.ParseFiles("layout.html","1.html"))
var t2 = template.Must(template.ParseFiles("layout.html","2.html"))
使用这样的变量:
err := t1.Execute(w, data)
问题中的代码和此代码中的此代码加载&#34; layout.html&#34;两次。这可以避免:
var layout = template.Must(template.ParseFiles("layout.html"))
var t1 = template.Must(layout.Clone().ParseFiles("1.html"))
var t2 = template.Must(layout.Clone().ParseFiles("2.html"))