为了账号安全,请及时绑定邮箱和手机立即绑定

如何在子目录中加载模板

如何在子目录中加载模板

Go
ibeautiful 2022-05-23 16:43:52
我目前将所有 html 文件都放在一个平面目录templates/中,并且我将所有内容都加载到tmpl := template.Must(template.ParseGlob("templates/*.html"))但我现在想引入一些结构并将模板放入文件夹、components、base等。但是当我这样做时,我的网站停止工作。我在想可能是上述情况,还是我需要引用模板中的路径?例子{{ template "navbar" }}会成为{{ template "components/navbar" }}有点迷茫...我现在也在使用本机 go 库而不是框架。
查看完整描述

1 回答

?
慕码人2483693

TA贡献1860条经验 获得超9个赞

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 为 nil。


当解析不同目录中的多个同名文件时,最后提到的将是结果。例如, 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" . }}。


查看完整回答
反对 回复 2022-05-23
  • 1 回答
  • 0 关注
  • 104 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信