You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go HTML模板跨目录引入报错:找不到nav模板

解决Go html/template找不到子目录模板的问题

这个报错的原因很明确:你当前的模板加载代码只读取了templates根目录下的.gohtml文件,而nav.gohtml放在了templates/includes子目录里,所以模板引擎根本没加载到它,自然找不到名为"nav"的模板。

问题根源

你的init函数里用了:

tpl = template.Must(template.ParseGlob("templates/*.gohtml"))

ParseGlob的通配符*.gohtml只会匹配templates目录下直接的文件,不会递归遍历子目录,所以includes/nav.gohtml完全没被加载。而header.gohtml和index.gohtml在同一目录,所以能正常被识别。

解决方案

这里有几种可行的解决方法,按推荐程度排序:

1. 递归加载所有子目录的模板文件(最推荐)

Go 1.16及以上版本支持filepath.Glob的**通配符,可以递归匹配所有子目录里的.gohtml文件。修改你的init函数:

import (
    "html/template"
    "log"
    "net/http"
    "path/filepath" // 新增这个包
)

var tpl *template.Template

func init() {
    // 递归获取templates目录下所有层级的.gohtml文件
    templateFiles, err := filepath.Glob("templates/**/*.gohtml")
    if err != nil {
        log.Fatalf("Failed to find template files: %v", err)
    }
    // 用ParseFiles加载所有找到的文件
    tpl = template.Must(template.ParseFiles(templateFiles...))
}

这样不管你把模板放在templates下的哪个子目录,都会被加载进来。

2. 显式列出所有模板文件(适合模板数量少的场景)

如果你的模板不多,可以直接在ParseFiles里把所有需要的文件路径都列出来:

func init() {
    tpl = template.Must(template.ParseFiles(
        "templates/index.gohtml",
        "templates/header.gohtml",
        "templates/includes/nav.gohtml",
        // 其他模板文件也可以在这里添加
    ))
}

这种方式虽然直观,但模板多了之后维护起来很麻烦,不推荐长期使用。

3. 检查模板定义是否正确

最后别忘了确认nav.gohtml里的模板定义格式是否正确,必须用{{define "nav"}}和{{end}}包裹内容,比如:

{{define "nav"}}
<nav>
    <a href="/">Home</a>
    <a href="/apply">Apply</a>
</nav>
{{end}}

如果没有这个定义,即使文件被加载了,模板引擎也找不到名为"nav"的模板。

验证修改

修改完代码后,重启你的Go服务,访问首页应该就不会再出现no such template "nav"的错误了。

内容的提问来源于stack exchange,提问作者Reza Saadati

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:07:49