How to parse multiple strings into a template with Go?

huangapple go评论81阅读模式
英文:

How to parse multiple strings into a template with Go?

问题

有没有像template.ParseFiles("base.html", "home.html")这样简单的方法,可以用于从一组字符串构建模板?

我有一个基础模板和一组页面模板(都是字符串),我想在基础模板上构建这些页面模板。

我已经找到了如何合并它们,但我的解决方案相当冗长,看起来不够优雅,尽管它能正常工作。

英文:

Is there a simple way like template.ParseFiles("base.html", "home.html") but for strings to build a template from a set of strings?

I have a base template and a list of pages templates (all as strings) that I want to build on top of base template.

I figured out how to merge them, but I my solution is quite verbose and doesn't look elegant enough, even though working.

答案1

得分: 6

您可以使用template.New()函数创建一个新的空模板。然后,您可以使用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.

相关问题请参考:https://stackoverflow.com/questions/41176355/go-template-name/41187671#41187671

注意:

虽然我们可以多次在单个模板上调用Template.Parse()方法,并且它可以正确解析多个命名模板,但仍建议为每个模板获取一个新的template.Template,通过调用Template.New()。因为如果模板文本中有命名模板之外的内容,它们将被覆盖,只有最后一个模板会被保留。例如:abc {{define "one"}}no 1{{end}}。静态文本"abc"将在后续的Template.Parse()调用中丢失。

这也在Template.Parse()的文档中有说明:

(在对同一个接收器模板进行多次调用Parse时,只有一个调用可以包含除空格、注释和模板定义之外的文本。)

英文:

You may create a new, empty template using template.New() function. Then you may use the Template.New() method to create a new, empty, associated template. And you may parse "into" this using the Template.Parse() method.

Here's how it could look like:

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
}

Testing it:

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)
}

Output (try it on the Go Playground):

I'm #2, including #1: I'm #1.

Also see related question: https://stackoverflow.com/questions/41176355/go-template-name/41187671#41187671

Note

While we could call the Template.Parse() method on a single template multiple times, and it would parse multiple named templates properly, it is still advisable to acquire a new template.Template for each by calling Template.New(). Because if the template texts have content outside of named templates, they will be overwritten and only the last would be retained. For example: abc {{define "one"}}no 1{{end}}. The static text "abc" would be lost by a subsequent Template.Parse() call.

This is also noted in the doc of Template.Parse():

> (In multiple calls to Parse with the same receiver template, only one call can contain text other than space, comments, and template definitions.)

答案2

得分: 0

也许

对于每个模板,使用以下代码:
for _, templ := range ListOfPagesTemplates{
    YourBaseTemplate.Parse(templ)
}

为了简化阅读,省略了错误检查。

英文:

Maybe

for _, templ := range ListOfPagesTemplates{
    YourBaseTemplate.Parse(templ)
}

err check absent for simplicity of reading

huangapple
  • 本文由 发表于 2017年1月25日 23:55:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/41856021.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定