根本原因是loadhtmlglob依赖当前工作目录而非源码目录;应使用filepath.abs(filepath.dir(os.args[0]))获取main.go所在绝对路径,再拼接模板路径,避免相对路径导致的匹配失败。

LoadHTMLGlob 通配符路径为什么总匹配不到文件?
根本原因是 LoadHTMLGlob 解析路径时依赖当前工作目录(os.Getwd()),不是源码所在目录。你在 IDE 里点运行,工作目录可能是项目根、IDE 插件目录,甚至 GOPATH,导致 "templates/*" 找不到任何文件,直接 panic:html/template: pattern matches no files。
- 用
filepath.Join(filepath.Dir(os.Args[0]), "templates")获取main.go所在目录下的templates绝对路径,再拼进LoadHTMLGlob -
"templates/**/*"看似能递归匹配,但 Gin 内部使用的是glob(非filepath.WalkDir),只支持一层**,且需模板中显式{{ define "subdir/file.html" }},否则渲染时按文件名查表会冲突 - 避免
"templates/**"—— 这会把子目录本身也当模板文件尝试编译,触发template: xxx is not a text template
多级目录模板怎么加载又不炸?
如果你的结构是 templates/layout/base.tmpl、templates/posts/list.tmpl,别硬扛 LoadHTMLGlob("templates/**/*")。它不可靠,且同名文件(如多个 index.tmpl)必须靠 define 区分,一漏就报错。
- 改用
filepath.WalkDir手动收集所有.tmpl或.html文件路径,生成字符串切片 - 传给
router.LoadHTMLFiles(tplPaths...)—— 这个函数不解析路径层级,只认你给的完整路径,渲染时也严格按你传入的路径字符串匹配c.HTML(200, "posts/list.tmpl", ...) - 注意:
LoadHTMLFiles不支持通配符,每个路径都得是真实存在的文件路径(含扩展名)
静态资源(CSS/JS)404 怎么破?
HTML 模板能渲染出来,但浏览器控制台一堆 GET /css/app.css 404?这不是模板问题,是 Gin 默认不提供静态服务 —— LoadHTMLGlob 只管服务端渲染,不管客户端请求的 CSS、JS、图片。
- 必须显式调用
r.Static("/css", "./templates/css"),让 URL 路径/css/xxx映射到磁盘路径./templates/css/xxx - 如果 HTML 里写的是
<link href="/static/css/main.css">,那就要注册r.Static("/static/css", "./assets/css"),路径前缀必须完全一致 - 别把静态资源和模板混放同一目录再幻想自动识别 —— Gin 不做这种猜测,一切映射靠你手动
Static
为什么在 Goland 里右键 run 就失败,命令行 go run 就行?
因为 Goland 默认把工作目录设为项目根,但你的 main.go 可能在 cmd/ 或 app/ 子目录下。这时 LoadHTMLGlob("templates/*") 实际查的是 项目根/templates/,而模板其实在 项目根/cmd/templates/。
- 最稳解法:不用相对路径,一律用
filepath.Abs(filepath.Dir(os.Args[0]))定位main.go目录,再拼模板路径 - 临时调试可在 Goland 的 Run Configuration → Working directory 改成
$ProjectFileDir$/cmd(按你实际路径调整) - CI/部署时更要禁用相对路径,否则不同构建环境行为不一致











