
Go 模板的 {{ template }} 动作默认不继承调用上下文,需显式传入当前数据(如 .)才能使被包含模板(如 nav.html)访问 .path 等变量。
go 模板的 `{{ template }}` 动作默认不继承调用上下文,需显式传入当前数据(如 `.`)才能使被包含模板(如 `nav.html`)访问 `.path` 等变量。
在 Go 的 text/template 包中,模板之间通过 {{ define }} 和 {{ template }} 实现复用,但一个关键特性常被忽略:{{ template "name" }} 本身不会自动将当前作用域(即 .)传递给被调用模板。它仅执行命名模板,而该模板内部的 . 默认为 nil(除非模板定义时明确接收参数)。
因此,您遇到的问题——nav.html 中 {{ .path }} 渲染为空——正是由于 {{ template "nav" }} 未传递任何数据,导致 . 在 nav 模板内不可用。
✅ 正确做法是:显式将当前上下文(.)作为参数传入:
<!-- index.html -->
{{ define "index" }}
{{ template "nav" . }} <!-- ✅ 传入当前数据对象 -->
<h1>Welcome to my website. You are visiting {{ .path }}.</h1>
{{ end }}
同时确保 nav.html 的定义保持简洁,直接使用 . 访问字段:
<!-- nav.html -->
{{ define "nav" }}
<nav class="nav-container"><h1>{{ .path }}</h1> <!-- ✅ 现在 .path 可正常解析 -->
</nav>
{{ end }}
? 补充说明:
{{ template "nav" . }}中的.是当前执行上下文(即parse映射转换后的结构体或 map),等价于{{ template "nav" $ }}或{{ template "nav" (dict "path" .path) }}(若需传递部分字段)。对于简单场景,直接传.最直观、最常用。
? 注意事项:
- 不要写成
{{ template "nav" }}(无参数)或{{ template "nav" nil }},这会导致子模板丢失数据; - 若使用嵌套层级更深(如
nav再包含logo.html),同样需逐层显式传递:{{ template "logo" . }}; - Martini 的
render.Render.HTML()方法传入的parse数据会作为根.注入主模板,因此只要主模板正确转发,所有子模板均可链式访问。
总结:Go 模板的数据流是显式而非隐式的。掌握 {{ template "name" . }} 这一模式,即可安全、清晰地实现跨模板变量共享,无需全局变量或复杂上下文管理。










