Go Template ParseFiles func 解析多个文件

xpt*_*xpt 2 templates go go-templates

如果我将两个或更多文件传递给 Go Template 的 ParseFiles 函数会发生什么?

func (*Template) ParseFiles
Run Code Online (Sandbox Code Playgroud)

它有助于说:

ParseFiles 解析命名文件并将生成的模板与 t 相关联。如果发生错误,则解析停止,返回的模板为零;否则就是 t。必须至少有一个文件。由于 ParseFiles 创建的模板由参数文件的基本名称命名,因此 t 通常应具有文件的(基本)名称之一的名称。如果没有,根据调用 ParseFiles 之前 t 的内容,t.Execute 可能会失败。在这种情况下,使用 t.ExecuteTemplate 来执行一个有效的模板。

当解析不同目录中的多个同名文件时,最后提到的将是结果。

但我仍然不确定影响输出的差异是什么,因为

MyTempl.ParseFiles(tf1)
Run Code Online (Sandbox Code Playgroud)

对比

MyTempl.ParseFiles(tf1, tf2)
Run Code Online (Sandbox Code Playgroud)

的内容tf2会附加到的内容tf1吗?

icz*_*cza 7

首先介绍一下“模板”概念:

template.Template值是“一个解析的模板的表示”。但这里的措辞有点“不完美”。一个template.Template值可以是(通常是)多个关联模板集合template.Template有一个未导出的字段:

tmpl   map[string]*Template // Map from name to defined templates.
Run Code Online (Sandbox Code Playgroud)

tmpl字段包含所有其他关联模板,模板可见的模板,并且可以通过其名称引用。

您可以在此答案中阅读有关此内容的更多信息:Go template name

回到Template.ParseFiles()方法。此方法从作为参数传递给它的文件中解析多个模板。从文件中解析出来的模板将以文件名命名(没有文件夹,只有文件名),并将它们添加到t方法接收者指定的模板的内部关联模板映射中。

不会附加解析的模板。template.Template将为它们创建多个单独的值,但它们将相关联(因此它们可以相互引用,例如它们可以相互包含)。

让我们看一个例子。假设我们有这两个模板文件:

a.html 是:

I'm a.
Run Code Online (Sandbox Code Playgroud)

并且b.html

I'm b.
Run Code Online (Sandbox Code Playgroud)

和一个示例代码:

t := template.New("a.html")
if _, err := t.ParseFiles("a.html", "b.html"); err != nil {
    panic(err)
}
if err := t.Execute(os.Stdout, nil); err != nil {
    panic(err)
}
Run Code Online (Sandbox Code Playgroud)

此示例创建一个名为 的新空模板a.html,然后解析 2 个文件:a.htmlb.html.

结果会怎样?t将表示a.html模板,因为我们之前使用该特定名称创建了它。运行代码,输出将是:

I'm a.
Run Code Online (Sandbox Code Playgroud)

现在,如果我们将第一行更改为:

t := template.New("x.html")
Run Code Online (Sandbox Code Playgroud)

其余部分保持不变,运行它我们会看到类似的内容:

panic: template: "x.html" is an incomplete or empty template
Run Code Online (Sandbox Code Playgroud)

原因是 thatt表示一个名为的模板,x.html但它是空的,因为我们没有将任何内容“解析为”它,并且解析的文件也与 name 不匹配x.html。因此尝试执行它会导致错误。

现在,如果我们尝试执行其关联的命名模板之一:

if err := t.ExecuteTemplate(os.Stdout, "a.html", nil); err != nil {
    panic(err)
}
Run Code Online (Sandbox Code Playgroud)

它成功了,并再次给出:

I'm a.
Run Code Online (Sandbox Code Playgroud)