Go 的 text/template 不支持直接按名称传参(如 foo=true),但可通过管道传递任意值作为子模板的 .(当前上下文),再在子模板中用 {{.}} 或局部变量引用。
go 的 `text/template` 不支持直接按名称传参(如 `foo=true`),但可通过管道传递任意值作为子模板的 `.`(当前上下文),再在子模板中用 `{{.}}` 或局部变量引用。
在 Go 模板中,{{template "name" pipeline}} 是向子模板(partial)传递数据的唯一标准方式。其中 pipeline 的求值结果会成为该子模板执行时的 .(即根作用域)。这意味着你无法像 Ruby 的 render partial: "_partial1", foo: true 那样显式命名参数,但可以通过结构化数据灵活模拟。
✅ 正确用法:传递结构体或映射实现“具名参数”
最实用且可扩展的方式是传递一个 map[string]interface{} 或自定义结构体,从而在子模板中以语义化方式访问字段:
parent.tmpl:
<div>
{{ template "partial1.tmpl" (dict "foo" true "title" "Welcome") }}
</div>
⚠️ 注意:dict 并非 Go 模板内置函数,需在解析前通过 Funcs 注册:
func main() { t := template.New("").Funcs(template.FuncMap{ "dict": func(values ...interface{}) map[string]interface{} { if len(values)%2 != 0 { panic("dict requires even number of arguments") } m := make(map[string]interface{}) for i := 0; i
_partial1.tmpl:
<div>
text1
{{if .foo}}
text2 (foo is true)
{{else}}
text2 (foo is false)
{{end}}
<h3>{{.title}}</h3>
</div>
✅ 替代方案:使用局部变量解构
若仅需少量参数,可在子模板内用 $ 命名局部变量提升可读性:
{{ $foo := . }}
<div>
text1
{{if $foo}}
text2
{{end}}
</div>
此时调用 {{template "partial1.tmpl" true}} 即可使 $foo 为 true。
❌ 常见误区
- {{template "partial1.tmpl" foo=true}} —— 语法错误,Go 模板不支持关键字参数;
- {{template "partial1.tmpl" .Foo}} —— 仅当父模板的 .(数据上下文)有 Foo 字段时才有效,但会丢失其他参数。
总结
Go 模板的参数传递本质是“上下文替换”而非“参数列表”。推荐实践:
- 简单场景:直接传布尔/字符串,用 {{.}} 判断;
- 生产项目:统一用 map 或结构体 + 自定义 dict 函数,保障可维护性与类型清晰性;
- 所有子模板应视为独立作用域,其 . 完全由 template 调用时的 pipeline 决定,与父模板 . 无关。











