template intro
程序员文章站
2022-07-07 09:47:39
...
Go的模板简介,基于1.9.2,具体细节还请参考godoc。
1. Overview
模板是含特定标签的字符串文本,按照固定语法将它解析为静态内存结构。该结构 + 输入数据对象 => 模板执行结果。
模板字符串是UTF-8。“Action”-数据和控制结构-以“{{”和“}}”分隔;action之外的文本原封不动输出。举例:
1.1 Action
下面是所有action。
{{/* a comment */}}
注释
{{pipeline}}
pipeline用于计算数据。输出其文本表示(同fmt.Print)
{{if pipeline}} T1 {{end}}
pipeline empty跳过;否则执行T1。empty指false|0|nil、或长度=0的array|slice|map|string。
{{if pipeline}} T1 {{else}} T0 {{end}}
not empty T1,否则T0
{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
{{range pipeline}} T1 {{end}}
pipeline的值应是array|slice|map|channel,遍历它的每个元素每次执行T1。pipeline长度=0时没有输出。
{{range pipeline}} T1 {{else}} T0 {{end}}
T0在pipeline长度=0时执行
{{template "name"}}
执行名称="name"的模板,输入数据=nil。注:一个模板可以关联多个模板(例如page header、page footer也是模板,嵌在大页面模板里 - 它们定义在一个字符串文本里)
{{template "name" pipeline}}
执行且输入数据=pipeline
{{block "name" pipeline}} T1 {{end}}
相当于定义"name"模板并马上执行它。注-定义模板:
{{define "name"}} T1 {{end}}
{{with pipeline}} T1 {{end}}
设置输入数据=pipeline,执行T1。如果pipeline empty,没有输出。
{{with pipeline}} T1 {{else}} T0 {{end}}
1.2 Argument
Argument是个简单值:
-boolean, string, character, integer, floating-point, imaginary or complex constant
-nil
-'.'(点号):当前数据(注:模板开始执行时当前数据=输入数据;遍历array时循环体内当前数据=array的当前元素,类推)
-变量名(以$开头),如“$piOver2”、“$”:该变量的值
-当前数据的某字段:.Field。可以嵌套:.Field1.Field2。也可以是变量的字段:$x.Field1.Field2
-当前数据是map时:.Key 取该key的值。可以嵌套:.Field1.Key1.Field2.Key2。也可以用于变量:$x.key1.key2
-调用当前数据的某方法:.Method - 方法需要有返回值。可以嵌套:.Field1.Key1.Method1.Field2.Key2.Method2。同样也可以用于变量
-函数调用:fun
-括号分隔如:(.StructValuedMethod "arg").Field
1.3 Pipeline
Pipeline是单个command或嵌套的一组command。Command是一个简单值(argument)、或一个函数|方法调用(可能有多个参数):
-Argument
-.Method [Argument...]
在当前数据上调用此方法:当前数据.Method(Argument1, etc.)。只有在嵌套链的末尾或单独使用时才能带参数
-functionName [Argument...]
调用该函数
在两个commands之间使用“|”做管道:前一个command的结果将作为后一个command的最后一个参数,如此嵌套。最后一个command的结果=该pipeline的结果。
1.4 Variable
定义并初始化一个变量:“$variable := pipeline”。
遍历时:“range $index, $element := pipeline”。
变量的作用域(scope)止于所在的if|with|range action,或模板结尾。
1.5 举例
以下所有例子均输出被引号包围的字符串output:
{{"\"output\""}}
string常量
{{`"output"`}}
raw string常量
{{printf "%q" "output"}}
函数调用
{{"output" | printf "%q"}}
printf函数的第二个参数来自前面command
{{printf "%q" (print "out" "put")}}
括号
{{"put" | printf "%s%s" "out" | printf "%q"}}
{{"output" | printf "%s" | printf "%q"}}
{{with "output"}}{{printf "%q" .}}{{end}}
在with action里,"."(当前数据)="output"
{{with $x := "output" | printf "%q"}}{{$x}}{{end}}
pipeline = “$x := "output" | printf "%q"”
{{with $x := "output"}}{{printf "%q" $x}}{{end}}
{{with $x := "output"}}{{$x | printf "%q"}}{{end}}
1.6 Function
函数来自于a)通过template.Funcs方法添加的、b)全局函数。
预定义的全局函数:
-and
返回第一个empty的argument、或最后一个argument。如“and x y”=“if x then y else x”。注意:由于是函数调用,所有argument都会被计算。
-call
函数调用,第一个参数代表一个函数,其余参数是该函数的调用参数。例如“.X.Y 1 2”:当前数据.X.Y应该=一个函数(例如map X.Y元素=函数、struct X.Y字段=函数)。
-html
参数的escaped HTML
-index
如“index x 1 2 3”=“x[1][2][3]”
-js
参数的escaped JavaScript
-len
参数的长度
-not
唯一参数的boolean 非
-or
返回第一个not empty的argument、或最后一个argument。如“or x y”=“if x then x else y”。同样,所有argument都会被计算
-print
fmt.Sprint
-printf
fmt.Sprintf
-println
fmt.Sprintln
-urlquery
参数escaped,用于URL query
boolean函数里零值(zero value)为false,非零值为true。
一组二元比较运算符:
-eq
arg1 == arg2
-ne
-lt
arg1 < arg2
-le
arg1 <= arg2
-gt
-ge
多个参数的eq比较相当于“arg1==arg2 || arg1==arg3 || arg1==arg4 ...”。例如模板
“{{if eq 123 13 2 456 123}}equals{{else}} not equals{{end}}”执行结果是“equals”。同样注意:eq是函数调用,所以每个argument都会被计算。
不能比较不同的基本类型,例如int和string无法比较。
1.7 关联模板
模板创建时要指定名称。一个模板可以再关联多个模板 - 这种关联是可传递的,形成了名称空间(TODO)。
1.8 嵌套模板定义
模板的字符串文本里可以定义多个模板。它们必须定义在顶层,以“define”和“end” action分隔。例如:
里面还定义了T1、T2、T3三个模板。该模板执行时会执行T3 - T3执行时会执行T1和T2。该模板执行输出:
一个模板只能存在于一个关联中。如果要从多个关联里存取同一个模板,只能构造多个该模板对象、或者调用Clone方法(TODO)。
用Execute方法执行模板,或用ExecuteTemplate方法执行指定的关联模板如:
2. Index
TODO
1. Overview
模板是含特定标签的字符串文本,按照固定语法将它解析为静态内存结构。该结构 + 输入数据对象 => 模板执行结果。
模板字符串是UTF-8。“Action”-数据和控制结构-以“{{”和“}}”分隔;action之外的文本原封不动输出。举例:
//struct 是输入数据对象 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) } //执行({{.XX}}对应sweaters.XX) err = tmpl.Execute(os.Stdout, sweaters) if err != nil { panic(err) }
1.1 Action
下面是所有action。
{{/* a comment */}}
注释
{{pipeline}}
pipeline用于计算数据。输出其文本表示(同fmt.Print)
{{if pipeline}} T1 {{end}}
pipeline empty跳过;否则执行T1。empty指false|0|nil、或长度=0的array|slice|map|string。
{{if pipeline}} T1 {{else}} T0 {{end}}
not empty T1,否则T0
{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
{{range pipeline}} T1 {{end}}
pipeline的值应是array|slice|map|channel,遍历它的每个元素每次执行T1。pipeline长度=0时没有输出。
{{range pipeline}} T1 {{else}} T0 {{end}}
T0在pipeline长度=0时执行
{{template "name"}}
执行名称="name"的模板,输入数据=nil。注:一个模板可以关联多个模板(例如page header、page footer也是模板,嵌在大页面模板里 - 它们定义在一个字符串文本里)
{{template "name" pipeline}}
执行且输入数据=pipeline
{{block "name" pipeline}} T1 {{end}}
相当于定义"name"模板并马上执行它。注-定义模板:
{{define "name"}} T1 {{end}}
{{with pipeline}} T1 {{end}}
设置输入数据=pipeline,执行T1。如果pipeline empty,没有输出。
{{with pipeline}} T1 {{else}} T0 {{end}}
1.2 Argument
Argument是个简单值:
-boolean, string, character, integer, floating-point, imaginary or complex constant
-nil
-'.'(点号):当前数据(注:模板开始执行时当前数据=输入数据;遍历array时循环体内当前数据=array的当前元素,类推)
-变量名(以$开头),如“$piOver2”、“$”:该变量的值
-当前数据的某字段:.Field。可以嵌套:.Field1.Field2。也可以是变量的字段:$x.Field1.Field2
-当前数据是map时:.Key 取该key的值。可以嵌套:.Field1.Key1.Field2.Key2。也可以用于变量:$x.key1.key2
-调用当前数据的某方法:.Method - 方法需要有返回值。可以嵌套:.Field1.Key1.Method1.Field2.Key2.Method2。同样也可以用于变量
-函数调用:fun
-括号分隔如:(.StructValuedMethod "arg").Field
1.3 Pipeline
Pipeline是单个command或嵌套的一组command。Command是一个简单值(argument)、或一个函数|方法调用(可能有多个参数):
-Argument
-.Method [Argument...]
在当前数据上调用此方法:当前数据.Method(Argument1, etc.)。只有在嵌套链的末尾或单独使用时才能带参数
-functionName [Argument...]
调用该函数
在两个commands之间使用“|”做管道:前一个command的结果将作为后一个command的最后一个参数,如此嵌套。最后一个command的结果=该pipeline的结果。
1.4 Variable
定义并初始化一个变量:“$variable := pipeline”。
遍历时:“range $index, $element := pipeline”。
变量的作用域(scope)止于所在的if|with|range action,或模板结尾。
1.5 举例
以下所有例子均输出被引号包围的字符串output:
{{"\"output\""}}
string常量
{{`"output"`}}
raw string常量
{{printf "%q" "output"}}
函数调用
{{"output" | printf "%q"}}
printf函数的第二个参数来自前面command
{{printf "%q" (print "out" "put")}}
括号
{{"put" | printf "%s%s" "out" | printf "%q"}}
{{"output" | printf "%s" | printf "%q"}}
{{with "output"}}{{printf "%q" .}}{{end}}
在with action里,"."(当前数据)="output"
{{with $x := "output" | printf "%q"}}{{$x}}{{end}}
pipeline = “$x := "output" | printf "%q"”
{{with $x := "output"}}{{printf "%q" $x}}{{end}}
{{with $x := "output"}}{{$x | printf "%q"}}{{end}}
1.6 Function
函数来自于a)通过template.Funcs方法添加的、b)全局函数。
预定义的全局函数:
-and
返回第一个empty的argument、或最后一个argument。如“and x y”=“if x then y else x”。注意:由于是函数调用,所有argument都会被计算。
-call
函数调用,第一个参数代表一个函数,其余参数是该函数的调用参数。例如“.X.Y 1 2”:当前数据.X.Y应该=一个函数(例如map X.Y元素=函数、struct X.Y字段=函数)。
-html
参数的escaped HTML
-index
如“index x 1 2 3”=“x[1][2][3]”
-js
参数的escaped JavaScript
-len
参数的长度
-not
唯一参数的boolean 非
-or
返回第一个not empty的argument、或最后一个argument。如“or x y”=“if x then x else y”。同样,所有argument都会被计算
fmt.Sprint
-printf
fmt.Sprintf
-println
fmt.Sprintln
-urlquery
参数escaped,用于URL query
boolean函数里零值(zero value)为false,非零值为true。
一组二元比较运算符:
-eq
arg1 == arg2
-ne
-lt
arg1 < arg2
-le
arg1 <= arg2
-gt
-ge
多个参数的eq比较相当于“arg1==arg2 || arg1==arg3 || arg1==arg4 ...”。例如模板
“{{if eq 123 13 2 456 123}}equals{{else}} not equals{{end}}”执行结果是“equals”。同样注意:eq是函数调用,所以每个argument都会被计算。
不能比较不同的基本类型,例如int和string无法比较。
1.7 关联模板
模板创建时要指定名称。一个模板可以再关联多个模板 - 这种关联是可传递的,形成了名称空间(TODO)。
1.8 嵌套模板定义
模板的字符串文本里可以定义多个模板。它们必须定义在顶层,以“define”和“end” action分隔。例如:
{{define "T1"}}ONE{{end}} {{define "T2"}}TWO{{end}} {{define "T3"}}{{template "T1"}} {{template "T2"}}{{end}} {{template "T3"}}
里面还定义了T1、T2、T3三个模板。该模板执行时会执行T3 - T3执行时会执行T1和T2。该模板执行输出:
ONE TWO
一个模板只能存在于一个关联中。如果要从多个关联里存取同一个模板,只能构造多个该模板对象、或者调用Clone方法(TODO)。
用Execute方法执行模板,或用ExecuteTemplate方法执行指定的关联模板如:
err := tmpl.Execute(os.Stdout, "no data needed") if err != nil { log.Fatalf("execution failed: %s", err) } err := tmpl.ExecuteTemplate(os.Stdout, "T2", "no data needed") if err != nil { log.Fatalf("execution failed: %s", err) }
2. Index
TODO
推荐阅读
-
JDBC Template基本使用方法详解
-
交给子类: Template Method(模板方法模式)【PHP】
-
详解使用vue-admin-template的优化历程
-
art-template的小demo分享(代码分析)
-
Go html/template 模板的使用实例详解
-
微信小程序使用template标签实现五星评分功能
-
python的Template使用指南
-
php Http_Template_IT类库进行模板替换
-
Vue.js学习记录之在元素与template中使用v-if指令实例
-
Android studio无法创建类和接口问题解决办法。提示 Unable to parse template "Class"