go 模板詳說

模板是咱們經常使用的手段用於動態生成頁面,或者用於代碼生成器的編寫等。好比把數據庫的表映射成go語言的struct,這些體力活,寫個代碼生成器是最合適不過的了.
示例例把錶轉成 struct :golang

固然這篇帖子不是寫關於代碼生成器的,是詳細說一下goTemplate,對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)
	}
複製代碼

輸出bash

hello world!
obj: map[age:18 name:world]
複製代碼

結構體內的字段也是用{{.field}}ui

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)
	}
複製代碼

空格

{{}}內添加 -能夠去掉空格spa

  • {{- }} 去掉左邊全部的空格
  • {{ -}} 去掉右邊全部的空格
  • {{- -}} 去掉兩邊全部的空格 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.
複製代碼

自定義變量

除了能夠直接使用go的對象,也能夠直接在模板中定義變量{{ $var := }},變量定義後,能夠在模板內其餘任意地方使用:code

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)
	}
複製代碼

輸出cdn

hello li
複製代碼

方法

方法能夠分爲全局方法和結構體方法還有內置方法,內置方法也是全局方法的一種對象

全局方法

template.FuncMap 是一個map裏面的value必需是方法,傳入的值的參數沒有限制blog

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 用於遍例數組,和gorange同樣,能夠直接獲得每一個變量,或者獲得 indexvalue

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)
	}
複製代碼
相關文章
相關標籤/搜索