go 模板详说

简介: go 模板详说

模板是我们常用的手段用于动态生成页面,或者用于代码生成器的编写等。比如把数据库的表映射成go语言的struct,这些体力活,写个代码生成器是最合适不过的了.
示例例把表转成 struct :

申请阿里云服务时,可以使用2000元阿里云代金券,阿里云官网领取网址:https://dashi.aliyun.com/site/yun/youhui

当然这篇帖子不是写关于代码生成器的,是详细说一下go的Template,对Template的操作熟悉了后,就可以利用他实现你想要的一些功能。

渲染对象
{{.}}来渲染对象本身,对象内部的字段可以{{.field}}
比如下面,我是用一个 map来存储的数据,访问key: name,并使用{{.}}来把 map打印出来
eg:

tmpl, err := template.New("test").Parse(`hello {{.name}}!
obj: {{.}}`)
if err != nil {
    panic(err)
}
err = tmpl.Execute(os.Stdout, map[string]interface{}{
    "name": "world", "age": 18})
if err != nil {
    panic(err)
}

输出

hello world!
obj: map[age:18 name:world]
结构体内的字段也是用{{.field}}

tmpl, err := template.New("test").Parse(`hello {{.Name}}!
obj: {{.}}`)
if err != nil {
    panic(err)
}
err = tmpl.Execute(os.Stdout, struct {
    Name string
    Age  int
}{Name: "li", Age: 18})
if err != nil {
    panic(err)
}

空格
在{{}}内添加 -可以去掉空格

{{- }} 去掉左边所有的空格
{{ -}} 去掉右边所有的空格
{{- -}} 去掉两边所有的空格
eg:

tmpl, err := template.New("test").Parse(`hello:    {{- .Name}}
age: {{.Age -}}   !!!
obj:     
{{- . -}}   end.`)
if err != nil {
    panic(err)
}
err = tmpl.Execute(os.Stdout, struct {
    Name string
    Age  int
}{Name: "li", Age: 18})
if err != nil {
    panic(err)
}

hello: 后面的空格到{{- .Name}} 之间的空格会被去掉.
{{.Age -}}到 !!!之间的空格会被去掉
obj:到{{- . -}}到 end.之间的空格都会被去掉。
hello:li
age: 18!!!
obj:{li 18}end.
阿里云服务器1核2G低至82元/年,阿里云官活动网址:https://dashi.aliyun.com/site/yun/aliyun 可以用20代金券,即102-20=82。

自定义变量
除了可以直接使用go的对象,也可以直接在模板中定义变量{{ $var := }},变量定义后,可以在模板内其他任意地方使用:

tmpl, err := template.New("test").Parse(`{{$a := "li"}} hello {{$a}}`)
if err != nil {
    panic(err)
}
err = tmpl.Execute(os.Stdout, nil)
if err != nil {
    panic(err)
}

输出

hello li
方法
方法可以分为全局方法和结构体方法还有内置方法,内置方法也是全局方法的一种

全局方法
template.FuncMap 是一个map里面的value必需是方法,传入的值的参数没有限制

type FuncMap map[string]interface{}
比如:定义一个ReplaceAll方法,替换所有的指定字符串
例子中把所有的zhang替换成li

tmpl, err := template.New("test").Funcs(template.FuncMap{
    "ReplaceAll": func(src string, old, new string) string {
        return strings.ReplaceAll(src, old, new)
    },
}).Parse(`func replace:  {{ReplaceAll .Name "zhang" "li"}}`)
if err != nil {
    panic(err)
}
err = tmpl.Execute(os.Stdout, struct {
    Name string
    Age  int
}{Name: "zhang_san zhang_si", Age: 18})
if err != nil {
    panic(err)
}

输出

func replace: li_san li_si
内置方法
模板有一些内置方法比如 call printf 等,和全局方法一样,直接调用就行

tmpl, err := template.New("test").Parse(`{{printf "name: %s age: %d" .Name .Age}}`)
if err != nil {
    panic(err)
}
err = tmpl.Execute(os.Stdout, struct {
    Name string
    Age  int
}{Name: "li", Age: 18})
if err != nil {
    panic(err)
}

输出

name: li age: 18
行为
常用的行为有if range template等

if
判断 {{if }} {{end}},可以用于字符串 bool 或者数值类型
当 字符串有数据 或者bool值为true 或者数值类型大于0 时为真

tmpl, err := template.New("test").Parse(`
name: {{.Name}} 
{{- if .Name}}
  string .Name true 
{{else}} 
  string .Name false 
{{end -}}
desc: {{.Desc}} 
{{- if .Desc}}
  string .Desc true 
{{else}} 
  string .Desc false 
{{end -}}
age: {{.Age}} 
{{- if .Age}}
  number .Age true 
{{else}} 
  number .Age true false
{{end -}}
isAdmin: {{.IsAdmin}} 
{{- if .Age}}
  bool .IsAdmin true 
{{else}} 
  bool .IsAdmin true false
{{end}}
`)
if err != nil {
    panic(err)
}
err = tmpl.Execute(os.Stdout, struct {
    Name    string
    Desc    string
    Age     int
    IsAdmin bool
}{Name: "", Desc: "xyz", Age: 18, IsAdmin: true})
if err != nil {
    panic(err)
}

输出:

name:  
  string .Name false 
desc: xyz
  string .Desc true 
age: 18
  number .Age true 
isAdmin: true
  bool .IsAdmin true

range
range 用于遍例数组,和go的 range一样,可以直接得到每个变量,或者得到 index 和value

tmpl, err := template.New("test").Parse(`
{{range .val}} {{.}} {{end}}
{{range $idx, $value := .val}} id: {{$idx}}: {{$value}} {{end}}`)
if err != nil {
    panic(err)
}
err = tmpl.Execute(os.Stdout, map[string]interface{}{
    "val": []string{"a", "b", "c", "d"}})
if err != nil {
    panic(err)
}

输出

a b c d
id: 0: a id: 1: b id: 2: c id: 3: d
内嵌template
除了可以在自定义对象还可以自定义内嵌的模板{{define "name"}},也可以传参数

tmpl, err := template.New("test").Parse(`
{{define "content"}} hello {{.}} {{end}}
content: {{template "content" "zhang san"}}`)
if err != nil {
    panic(err)
}
err = tmpl.Execute(os.Stdout, nil)
if err != nil {
    panic(err)
}

在调用时{{template "content" "zhang san"}} 传递了参数 zhang san
输出:

content: hello zhang san
注释
模板的注释: {{/ comment /}}

tmpl, err := template.New("test").Parse(`
{{/* 注释 */}}
{{define "content"}} hello {{.}} {{end}}
content: {{template "content" "zhang san"}}`)
if err != nil {
    panic(err)
}
err = tmpl.Execute(os.Stdout, nil)
if err != nil {
    panic(err)
}
相关文章
|
7月前
|
安全 Go
Golang深入浅出之-Go语言模板(text/template):动态生成HTML
【4月更文挑战第24天】Go语言标准库中的`text/template`包用于动态生成HTML和文本,但不熟悉其用法可能导致错误。本文探讨了三个常见问题:1) 忽视模板执行错误,应确保正确处理错误;2) 忽视模板安全,应使用`html/template`包防止XSS攻击;3) 模板结构不合理,应合理组织模板以提高可维护性。理解并运用这些最佳实践,能提升Go语言模板编程的效率和安全性,助力构建稳健的Web应用。
96 0
|
4月前
|
自然语言处理 搜索推荐 Go
goctl 技术系列 - Go 模板入门
goctl 技术系列 - Go 模板入门
|
4月前
|
搜索推荐 Go UED
揭秘 Go 中的模板:一份全面而广泛的指南
揭秘 Go 中的模板:一份全面而广泛的指南
|
7月前
|
安全 Go 开发者
Golang深入浅出之-Go语言模板(text/template):动态生成HTML
【4月更文挑战第25天】Go语言的`text/template`和`html/template`库提供动态HTML生成。本文介绍了模板基础,如基本语法和数据绑定,以及常见问题和易错点,如忘记转义、未初始化变量、复杂逻辑处理和错误处理。建议使用`html/template`防止XSS攻击,初始化数据结构,分离业务逻辑,并严谨处理错误。示例展示了条件判断和循环结构。通过遵循最佳实践,开发者能更安全、高效地生成HTML。
276 0
|
设计模式 算法 Go
Go的模板方式模式
模板方法模式是一种行为设计模式,它在一个抽象类中定义了一个算法的骨架,允许子类为算法的某些步骤提供具体实现。它促进了代码的重用,并为一组相关算法定义了一个通用的结构。
56 0
|
存储 JSON 缓存
彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-模板与数据库EP02
书接上回,上次我们搭建好了项目入口文件,同时配置了路由体系,接着就可以配置项目的模板了,这里我们采用Iris内置的模板引擎,事实上,采用模板引擎并不意味着前后端耦合,模板中的数据保持其独立性即可,也就是说模板的数据操作交互方式采用http接口请求的形式,Iris并不参与模板逻辑,只返回Json格式的数据即可。前端集成数据双向绑定机制的框架Vue.js。
彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-模板与数据库EP02
|
安全 测试技术 Go
Go --- html/template模板包的使用(二)
Go --- html/template模板包的使用
Go --- html/template模板包的使用(二)
|
SQL 开发框架 JavaScript
Go --- html/template模板包的使用(一)
Go --- html/template模板包的使用
Go --- html/template模板包的使用(一)
Go语言之自定义模板,修改模板默认变量符号
Go语言之自定义模板,修改模板默认变量符号
111 0
Go语言之自定义模板,修改模板默认变量符号
Go语言之自定义模板,引用多个模板html文件嵌套使用
Go语言之自定义模板,引用多个模板html文件嵌套使用
296 0
Go语言之自定义模板,引用多个模板html文件嵌套使用