Go 的 html/template 通过 define/template 指令模拟模板继承:先定义 base.html 声明 title/content 等命名区块,子模板 home.html 重定义这些区块并调用 {{template "base.html" .}} 实现覆盖;需按顺序解析到同一 template 实例,执行时用 ExecuteTemplate 指定子模板名。

在 Go 的 html/template 包中,原生不支持类似 Django 或 Jinja2 的“模板继承”语法(如 {% extends %}、{% block %}),但可以通过组合使用 模板嵌套 和 define / template 指令 模拟出功能完整、结构清晰的继承机制,显著提升 HTML 模板复用性。
定义基础布局模板(base.html)
这是所有页面共用的骨架,包含通用的 HTML 结构、头部资源、导航栏和页脚,并预留可被子模板填充的“占位区块”。
关键点:用 {{define "name"}}...{{end}} 声明命名区块,用 {{template "name" .}} 渲染它(注意传参保持上下文一致)。
示例 base.html:
立即学习“go语言免费学习笔记(深入)”;
{{template "title" .}} 我的网站
{{template "content" .}}
创建子模板并覆盖区块(home.html)
子模板通过 {{define}} 重新定义父模板中已声明的区块名,再用 {{template "base.html" .}} 主动调用基础模板——Go 模板的执行顺序决定了“子定义优先于父定义”,从而实现覆盖效果。
注意:必须先解析 base.html,再解析子模板;且子模板中不能遗漏对基础模板的显式调用。
示例 home.html:
{{define "title"}}首页 - MySite{{end}}
{{define "content"}}
欢迎来到首页
这里是动态内容区域。
{{end}}{{template "base.html" .}}
在 Go 代码中正确解析与执行
模板需按依赖顺序解析(先 base,后子模板),且所有模板必须在同一个 *template.Template 实例中注册,才能跨文件引用。
- 使用
template.New("base").ParseFiles("base.html")初始化 - 再用
tmpl.ParseFiles("home.html")加载子模板(自动合并到同一实例) - 执行时指定子模板名:
tmpl.ExecuteTemplate(w, "home.html", data)
错误做法:分别创建独立模板实例,会导致 template "base.html" 找不到。
进阶技巧:支持多级继承与动态区块
可通过嵌套 {{template}} 实现“布局 → 页面 → 组件”三级结构;也可利用 . 上下文传递字段,在区块中做条件渲染。
例如,在 base.html 中定义可选侧边栏:
{{if .Sidebar}}
子模板中按需提供 Sidebar: true 并定义 "sidebar" 区块即可启用。











