Go模板引擎 嵌套模版

在实际项目中,我们不可能只有一个模板,一般来说都有很多个模板,而且这些模板也会共享一些公共的模板,这些公共的模板我们都可以定义成子模板,在需要的时候调用子模板,就可以将子模板的内容嵌入当前模板中。

提示:在项目中使用子模板,可以让项目模板具有模块化的能力,提高模块复用能力和可维护性。

1. 定义子模板

定义子模板语法:

{{define "子模板名字"}}
模板内容
{{end}}

例子:

{{define "T1"}}
模板内容T1
{{end}}

{{define "T2"}}
模板内容T2
{{end}}

2. 调用子模板

调用子模板语法:

{{template "子模板名字" 参数}}

template函数的第一个参数是模板名字,第二个参数是模板参数, 在子模板内部也是通过点( . ),引用模板参数。

提示: template的第二个模板参数是可选的。

例子:

//模板代码
//这里定义了T1 T2 T3三个模板,T3调用了T1和T2的模板内容,最后我们调用T3模板内容
const templateText = `{{define "T1"}}ONE{{end}}
{{define "T2"}}TWO{{end}}
{{define "T3"}}{{template "T1"}} {{template "T2"}}{{end}}
{{template "T3"}}`


// 创建一个template对象,模板名字为test,然后调用Parse加载templateText模板代码。
tmpl, err := template.New("test").Parse(templateText)
if err != nil {
    log.Fatalf("解析模板失败: %s", err)
}

// 渲染模板
err = tmpl.Execute(os.Stdout, "")
if err != nil {
	log.Fatalf("渲染模板失败: %s", err)
}

输出:

ONE TWO

3. 模板管理

上面的例子,我们将模板代码定义在一个变量或者常量中,这个只是用于演示,实际项目中模板代码通常非常多,建议大家按如下方式组织模板代码:

  • 一个模块的模板代码,保存在一个模板文件中,模板文件名为tpl。
  • 所有的模板代码都定义在子模板中,方便根据模板名字进行渲染。

例子:模板目录views, 下面分别按功能模块创建不同的模板文件

创建公共模板文件: views/common.tpl 主要用于保存一些公共的模板定义

{{define "common1"}}
这里是共享模块1
{{end}}

{{define "common2"}}
这里是共享模块2
{{end}}

创建 mod1 模块的模板文件: views/mod1.tpl

{{define "mod1"}}
这里是模块1
{{- template "common1"}}
{{end}}

创建 mod2 模块的模板文件: views/mod2.tpl

{{define "mod2"}}
这里是模块2
{{- template "common2"}}
{{end}}

渲染模板代码:

//创建template对象,并且加载views目录下面所有的tpl模板文件。
t := template.Must(template.ParseGlob("views/*.tpl"))

// 渲染mod1子模板
t.ExecuteTemplate(os.Stdout, "mod1", nil)

// 渲染mod2子模板
t.ExecuteTemplate(os.Stdout, "mod2", nil)

输出:

这里是模块1
这里是共享模块1

这里是模块2
这里是共享模块2