我们可以通过{{define "home"}}
定义模板名称,然后通过{{template "home"}}
将其加载到其他(父)模板中。
如何通过变量值{{template .TemplateName}}
加载模板。或者它不可能?
答案 0 :(得分:12)
很遗憾,你不能。
{{template}}
操作的语法:
{{template "name"}}
The template with the specified name is executed with nil data.
{{template "name" pipeline}}
The template with the specified name is executed with dot set
to the value of the pipeline.
要包含的模板的名称是常量字符串,它不是管道,它可能在执行期间根据参数而变化。
如果允许的语法是:
{{template pipeline}}
那么你可以使用{{template .TemplName}}
这样的东西,但由于语法只允许使用常量字符串,所以你不能。
Rob的推理为什么不允许动态模板调用(source):
我们希望模板语言可以静态分析,因此模板调用的上下文是清晰,可检查和可锁定的。如果调用点完全是动态的,则无法完成。类似地,如果模板可以属于多个集合,则其上下文可以以需要同时分析所有集合的方式在集合之间不同。由于这两个约束很容易解决,如果你想以更高级别的包丢失那些静态检查为代价,控制基本模板实现中的情况似乎是明智的。如果约束条件清晰,则更高级别的包(例如假设的仅HTML包装器)可以保证不会更容易解决。
您可以做的是先执行您想要包含的模板,然后将结果插入您想要包含的模板。您可以使用特殊类型在插入时不要转义内部模板的结果,例如在HTML模板的情况下使用html.HTML
。
见这个例子:
func main() {
t := template.Must(template.New("t").Parse(t))
template.Must(t.New("t1").Parse(t1))
params := struct {
Name string
Value interface{}
}{"t1", nil}
b := bytes.Buffer{}
t.ExecuteTemplate(&b, params.Name, nil)
params.Value = template.HTML(b.String())
t.Execute(os.Stdout, params)
}
const t = `<html><body>
Now I will include template with name: {{.Name}}
{{.Value}}
</body>/html>`
const t1 = `I'm template <b>t1</b>.`
输出:
<html><body>
Now I will include template with name: t1
I'm template <b>t1</b>.
</body>/html>
在Go Playground上尝试。
模板t1
的结果未插入。如果你遗漏template.HTML
:
params.Value = b.String()
t1
将被插入转义,如下所示:
<html><body>
Now I will include template with name: t1
I'm template <b>t1</b>.
</body>/html>
您可以重新构建模板,而不是在您希望包含具有不同名称的模板的情况下。
示例:您可能希望创建一个页面,其中包含page
模板,如下所示:
<html><body>
Title, headers etc.
{{template .Page}}
Footers
</body></html>
您可以将其重组为:
header
模板:
<html><body>
Title, headers, etc.
footer
模板:
Footers
</body></html
您的网页模板包含header
和footer
,如下所示:
{{template "header" .}}
Page content comes here.
{{template "footer" .}}
{{if}}
操作和预定义名称如果您之前知道模板名称并且它不是令人筋疲力尽的列表,则可以使用{{if}}
模板操作来包含所需的模板。例如:
{{if eq .Name "page1"}}
{{template "page1" .}}
{{else if eq .Name "page2"}}
{{template "page2" .}}
...
{{end}}
这里的想法是您可以手动修改外部模板的静态文本,并插入要包含的内部模板的名称。
此方法的缺点是,在插入内部模板的名称后,您必须重新解析模板,因此我不建议这样做。