
在go模板中,使用`{{template "name"}}`调用子模板时默认不传递数据,导致如`.title`等字段在header等partial模板中为空;正确做法是显式传入当前上下文:`{{template "header.html" .}}`。
当你在主模板 post.html 中写 {{template "header.html"}} 时,Go 的 text/template 包会以空数据(nil)为上下文渲染 header.html —— 这意味着 {{.Title}} 实际上是在 nil 上求值,自然输出为空字符串,而不会继承父模板的 .Page 数据。
✅ 正确写法是显式将当前数据(即 .,代表传入 Execute 的 Page 实例)作为第二个参数传递给 template 动作:
<!-- templates/post.html -->
{{template "header.html" .}} <!-- 注意:添加了 "." -->
<article>
{{.Body}}
</article>
{{template "footer.html" .}} <!-- 同理,footer若需访问.Page也可传. -->这样,header.html 就能在其执行上下文中正确访问 {{.Title}} 和 {{.Body}} 等字段。
⚠️ 注意事项:
- {{template "name"}} 和 {{template "name" .}} 语义完全不同:前者无数据,后者继承当前作用域;
- 若 partial 模板需要不同结构的数据(例如 header 需要 SiteName 而非 Page),建议使用 {{define}} + {{template ... $data}} 显式构造上下文,或通过嵌套结构体预组织数据;
- 所有被 template 引用的子模板(如 header.html、footer.html)必须在 ParseGlob 或 ParseFiles 中一并加载,否则运行时报 template: "header.html" is undefined。
? 补充技巧:你还可以为 partial 定义带参数的模板(Go 1.12+ 支持命名参数),但对简单场景,{{template "name" .}} 是最直接、最符合直觉的解法。
总结:Go 模板的 template 动作默认“隔离”数据上下文,打破隔离只需一步——显式传参 .。这是理解 Go 模板数据流的关键原则之一。


















