go学习笔记——text template
golang可以使用text/template来实现模板生成文本,官方文档:https://pkg.go.dev/text/template
1.变量
可以在模板中定义变量,然后将这些变量赋值到模板的变量中
import "text/template"
// 定义结构体
type Inventory struct {
	Material string
	Count    uint
}
// 赋值
sweaters := Inventory{"wool", 17}
// 定义模板
tmpl, err := template.New("test").Parse(`
	{{.Count}} items are made of {{.Material}}
`)
if err != nil {
	panic(err)
}
// 填充模板
err = tmpl.Execute(os.Stdout, sweaters)
if err != nil {
	panic(err)
}
输出
17 items are made of wool
2.if else
1.判断字符串是否相等
{{ if eq .Material "wool" }}
  Material is "wool"
{{ else if eq .Material "not wool" }}
  Material is not "wool"
{{ end }}
{{ if eq .Count 17 }}
  Count is 17
{{ else if eq .Count 10 }}
  Count is not 10
{{ end }}
输出
Material is "wool" Count is 17
2.多条件,与或非
{{ if or (eq .Material "not wool") (eq .Count 17) }}
  Count is 17
{{ end }}
输出
Count is 17
3.for循环
1.遍历数组
在for循环中使用其他变量的时候,要用{{$.xxx}}
取得index和value,使用{{$index}}和{{$value}}
{{range $index, $value := .Ips}}
   index: {{$index}}, material: {{$.Material}}, value: {{$value}}
{{end}}
输出
index: 0, material: wool, value: 192.168.0.1 index: 1, material: wool, value: 192.168.0.2
2.遍历map
同样也可以使用for循环遍历map,取得key和value
type Inventory struct {
	Material string
	Count    uint
	Ips      []string
	Maps     map[string]string
}
sweaters := Inventory{
	"wool",
	17,
	[]string{"192.168.0.1", "192.168.0.2"},
	map[string]string{
		"key":   "hello",
		"value": "world",
	},
}
tmpl, err := template.New("test").Parse(`
	{{range $key, $value := .Maps}}
	   key: {{$key}}, material: {{$.Material}}, value: {{$value}}
	{{end}}
`)
if err != nil {
	panic(err)
}
err = tmpl.Execute(os.Stdout, sweaters)
if err != nil {
	panic(err)
}
4.函数
1.len函数
判断数组的长度是否等于1,其中Ips可以是切片或者map
{{if eq (len .Ips) 1}}
len=1
{{else if eq (len .Ips) 2}}
len=2
{{else}}
other
{{end}}
2.index函数
可以使用index函数获得数组特定下标的值
{{index .Ips 0}}
如果和eq函数一起使用
{{if or (eq (index .Ips 0) "192.168.0.1") (eq (index .Ips 1) "192.168.0.2")}}
{{end}}
3.for循环下标从1开始
参考:golang template(数组循环、在循环内使用外部变量、索引从1开始)
4.自定义函数
可以自定义函数来自己实现函数
package main
import (
	"bytes"
	"strings"
	"text/template"
)
func main() {
	type Inventory struct {
		Material string
		Count    uint
		Ips      []string
		Maps     map[string]string
	}
	sweaters := Inventory{
		"test1,test2",
		17,
		[]string{"192.168.0.1", "192.168.0.2"},
		map[string]string{
			"key":   "hello",
			"value": "world",
		},
	}
	tmpl := template.New("test")
	funcs := template.FuncMap{
		"hasSuffix":   strings.HasSuffix,
		"split":       strings.Split,
		"containItem": containItem,
		"renderTemplate": func(name string, data interface{}) (string, error) {
			var buf bytes.Buffer
			err := tmpl.ExecuteTemplate(&buf, name, data)
			return buf.String() + " test", err
		},
	}
	temp, err := tmpl.Funcs(funcs).Parse(
		`
		{{if hasSuffix .Material "test2"}}
			hasSuffix
		{{end}}
	`)
	if err != nil {
		panic(err)
	}
	var output bytes.Buffer
	err = temp.Execute(&output, sweaters)
	if err != nil {
		panic(err)
	}
	str := output.String()
	println(str)
}
func containItem(slice []string, item string) bool {
	for _, v := range slice {
		if v == item {
			return true
		}
	}
	return false
}
判断字符串是否包含特定后缀
{{if hasSuffix .Material "test2"}}
	hasSuffix
{{end}}
将字符串以特定字符切分成数组,然后遍历
{{- $items := split .Material "," -}}
{{- range $index, $item := $items -}}
	{{$item}}
{{end}}
输出
test1
                test2
判断切片是否包含特定字符串
{{if containItem .Ips "192.168.0.1"}}
	containItem
{{end}}
5.其他
1.注释
{{/* 注释 */}}
2.子模板
可以在template中使用define关键字定义一个子模板,然后使用template关键字添加这个子模板
start define a template
{{- define "T1" -}}
   define a template
{{- end -}}
{{template "T1" .}}
end define a template
输出
                start define a template
                
                
                        define a template
                
                end define a template
3.去除空格
可以看到上面渲染出来的字符串中有很多的空格,可以使用 - 来去掉多余的空格
比如去掉前面的空格
{{- "start define a template"}}
去掉后面的空格
{{"start define a template"}}
去掉模板前后,和模板中的空格
{{- "start define a template" -}}
{{define "T1" -}}
define a template
{{- end}}
{{- template "T1" . -}}
{{- "end define a template" -}}
输出
start define a templatedefine a templateend define a template
4.将子模板定义成一个变量,并使用函数进行处理后输出
package main
import (
	"bytes"
	"text/template"
)
func main() {
	type Inventory struct {
		Material string
		Count    uint
		Ips      []string
		Maps     map[string]string
	}
	sweaters := Inventory{
		"wool",
		17,
		[]string{"192.168.0.1", "192.168.0.2"},
		map[string]string{
			"key":   "hello",
			"value": "world",
		},
	}
	tmpl := template.New("test")
	funcs := template.FuncMap{
		"renderTemplate": func(name string, data interface{}) (string, error) {
			var buf bytes.Buffer
			err := tmpl.ExecuteTemplate(&buf, name, data)
			return buf.String() + " test", err
		},
	}
	temp, err := tmpl.Funcs(funcs).Parse(
		`
		{{define "T1" -}}
		define a template
		{{- end}}
		{{define "T111"}}
			{{- $message := renderTemplate "T1" . -}}
			{{$message}}
		{{end}}
		{{template "T111" .}}
	`)
	if err != nil {
		panic(err)
	}
	var output bytes.Buffer
	err = temp.Execute(&output, sweaters)
	if err != nil {
		panic(err)
	}
	str := output.String()
	println(str)
}
本文只发表于博客园和tonglin0325的博客,作者:tonglin0325,转载请注明原文链接:https://www.cnblogs.com/tonglin0325/p/18835627
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号