gin模板需手动加载且严格校验:必须在r.run()前调用r.loadhtmlglob或r.loadhtmlfiles,路径错误、语法错误或模板名不一致均导致panic;{{template}}须显式传参如{{template "name" .}};静态资源需单独配置r.static;struct字段须首字母大写。

c.HTML 是 Gin 渲染模板的唯一入口,它不自动加载、不自动继承、不自动解析嵌套——所有行为都由你显式控制。
模板文件必须手动加载,否则 c.HTML 会 panic
Gin 不会在运行时扫描目录或按需加载模板。你必须在 r := gin.Default() 之后、r.Run() 之前调用加载函数:
-
r.LoadHTMLGlob("templates/**/*.tmpl"):推荐,支持通配符,一次加载多级子目录下的所有.tmpl文件 -
r.LoadHTMLFiles("templates/base.tmpl", "templates/home.tmpl"):适合小项目或需精确控制加载顺序的场景 - 若路径错误、文件不存在、或模板语法有误(如未闭合
{{),LoadHTML*会直接 panic,而不是延迟报错
{{template}} 嵌入局部模板时,作用域默认不继承
你在主模板里用 {{template "header" .}} 调用子模板,那个 . 才把当前上下文传进去。漏掉这个点号,子模板里访问 {{.Title}} 就是 nil:
- 定义局部模板用
{{define "header"}},不能带空格或特殊字符,名字要和template调用时完全一致 -
{{template "header"}}→ 子模板收不到数据;{{template "header" .}}→ 正确传递整个上下文 - 如果只想传部分字段,可构造新 map:
{{template "card" (dict "Name" .User.Name "ID" .User.ID)}}(需提前注册dict函数)
结构化数据必须用 gin.H 或自定义 struct 传入
gin.H 是 map[string]interface{} 的别名,方便快速构造键值对。但它不支持方法调用、不支持嵌套模板中直接解构指针:
- 传切片:
"items": []string{"a", "b"},模板中用{{range .items}}{{.}}{{end}} - 传 struct:
"user": User{Name: "Alice", Age: 30},模板中用{{.user.Name}},注意大小写敏感 - 避免传
*User指针后在模板里调{{.user.Method()}}——html/template默认不导出未导出字段和方法,会静默失败
静态资源路径不会被模板引擎处理,必须单独配置
模板里的 <link href="/static/css/app.css"> 这类路径,Gin 完全不管。你得自己加静态路由:
-
r.Static("/static", "./static"):把本地./static目录映射到/staticURL 前缀 - 路径必须以
/开头,且与模板中写的 URL 前缀严格一致(比如模板写/assets/,就得配r.Static("/assets", "./public")) - 没有这行代码,浏览器请求
/static/xxx.css会返回 404,且 Gin 不会提示“你忘了配静态路由”
LoadHTMLGlob 路径没匹配到任何文件却没报错(因为 glob 匹配为空时函数不 panic)、以及 struct 字段没首字母大写导致模板里取不到值——这三处问题都不会抛出明确错误,只会渲染出空内容。











