我目前将所有 html 文件都放在一个平面目录中templates/,并使用以下命令加载所有内容
tmpl := template.Must(template.ParseGlob("templates/*.html"))
但我现在想引入一些结构并将模板放入文件夹、、components等中base。但是当我这样做时,我的网站停止工作。我想可能是上面的情况,或者也可能是我需要引用模板中的路径?
例子
{{ template "navbar" }}
会成为
{{ template "components/navbar" }}
有点迷茫...
目前我还使用原生 go 库而不是框架。
Go的glob不支持匹配子目录中的文件,即**不支持。
您可以使用第三方库(github 上有许多实现),或者您可以调用filepath.Glob子目录的每个“级别”并将返回的文件名聚合到单个切片中,然后将该切片传递给template.ParseFiles:
dirs := []string{
    "templates/*.html",
    "templates/*/*.html",
    "templates/*/*/*.html",
    // ...
}
files := []string{}
for _, dir := range dirs {
    ff, err := filepath.Glob(dir)
    if err != nil {
        panic(err)
    }
    files = append(files, ff...)
}
t, err := template.ParseFiles(files...)
if err != nil {
    panic(err)
}
// ...
您还需要记住如何ParseFiles工作:(强调我的)
ParseFiles 创建一个新模板并从命名文件中解析模板定义。返回的模板的名称将具有第一个文件的(基本)名称和(已解析)内容。必须至少有一个文件。如果发生错误,解析将停止并且返回的 *Template 为零。
当解析不同目录中具有相同名称的多个文件时,最后提到的文件将是结果。例如,ParseFiles("a/foo", "b/foo") 将“b/foo”存储为名为“foo”的模板,而“a/foo”不可用。
这意味着,如果要加载所有文件,则必须确保至少以下两件事之一:(1) 每个文件的基本名称在所有模板文件中都是唯一的,而不仅仅是在文件所在的目录中,或 (2) 使用{{ define "<template_name>" }}文件内容顶部的操作为每个文件提供唯一的模板名称(并且不要忘记{{ end }}关闭define操作)。
作为第二种方法的示例,假设在您的模板中您有两个具有相同基本名称的文件,例如templates/foo/header.html和templates/bar/header.html,它们的内容如下:
templates/foo/header.html
<head><title>Foo Site</title></head>
templates/bar/header.html
<head><title>Bar Site</title></head>
现在,要给这些文件一个唯一的模板名称,您可以将内容更改为:
templates/foo/header.html
{{ define "foo/header" }}
<head><title>Foo Site</title></head>
{{ end }}
templates/bar/header.html
{{ define "bar/header" }}
<head><title>Bar Site</title></head>
{{ end }}
执行此操作后,您可以直接使用 执行它们t.ExecuteTemplate(w, "foo/header", nil),也可以通过让其他模板使用该{{ template "bar/header" . }}操作引用它们来间接执行它们。
| 归档时间: | 
 | 
| 查看次数: | 1165 次 | 
| 最近记录: |