【发布时间】:2017-01-25 15:55:37
【问题描述】:
有没有像template.ParseFiles("base.html", "home.html") 这样的简单方法,但要让字符串从一组字符串构建模板?
我有一个基本模板和一个页面模板列表(全部作为字符串),我想在基本模板之上构建。
我想出了如何合并它们,但我的解决方案非常冗长,看起来不够优雅,即使可以工作。
【问题讨论】:
标签: templates go go-templates
有没有像template.ParseFiles("base.html", "home.html") 这样的简单方法,但要让字符串从一组字符串构建模板?
我有一个基本模板和一个页面模板列表(全部作为字符串),我想在基本模板之上构建。
我想出了如何合并它们,但我的解决方案非常冗长,看起来不够优雅,即使可以工作。
【问题讨论】:
标签: templates go go-templates
您可以使用template.New() function 创建一个新的空模板。然后您可以使用Template.New() 方法 创建一个新的、空的、关联 模板。您可以使用Template.Parse() 方法将其“解析”成。
下面是它的样子:
func parseTemplates(templs ...string) (t *template.Template, err error) {
t = template.New("_all")
for i, templ := range templs {
if _, err = t.New(fmt.Sprint("_", i)).Parse(templ); err != nil {
return
}
}
return
}
测试它:
t, err := parseTemplates(
`{{define "one"}}I'm #1.{{end}}`,
`{{define "two"}}I'm #2, including #1: {{template "one" .}}{{end}}`,
)
if err != nil {
panic(err)
}
if err = t.ExecuteTemplate(os.Stdout, "two", nil); err != nil {
panic(err)
}
输出(在Go Playground上试试):
I'm #2, including #1: I'm #1.
另见相关问题:Go template name
虽然我们可以在单个模板上多次调用 Template.Parse() 方法,并且它会正确解析多个 named 模板,但仍然建议通过调用为每个模板获取一个新的 template.Template Template.New()。因为如果模板文本的内容在命名模板之外,它们将被覆盖,只保留最后一个。例如:abc {{define "one"}}no 1{{end}}。后续的Template.Parse() 调用将丢失静态文本"abc"。
Template.Parse() 的文档中也提到了这一点:
(在使用同一个接收者模板多次调用 Parse 时,只有一次调用可以包含除空格、cmets 和模板定义之外的文本。)
【讨论】:
也许
for _, templ := range ListOfPagesTemplates{
YourBaseTemplate.Parse(templ)
}
为了阅读方便,没有错误检查
【讨论】:
Template.New()为每个模板获取新的template.Template在命名模板之外,它们将被覆盖,仅保留最后一个。示例:abc {{define "one"}}no 1{{end}}。静态文本"abc" 将被后续的Parse() 丢失。详情见我的回答。