模板语法
移除空格有时候我们在使用模板语法的时候会不可避免的引入一下空格或者换行符,这样模板最终渲染出来的内容可能就和我们想的不一样,这个时候可以使用{{-语法去除模板内容左侧的所有空白符号,使用-}}去除模板内容右侧的所有空白符号。
例如:{{- .name -}} 注意:-要紧挨{{和}},同时与模板值之间需要使用空格分隔。
条件判断Go模板语法中条件判断有以下几种:
{{if pipeline}} T1 {{end}} {{if pipeline}} T1 {{else}} T0 {{end}} {{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
rangeGo的模板语法中使用range关键字进行遍历,有以下两种写法,其中pipeline的值必须是数组、切片、字典或者通道。
{{range pipeline}} T1 {{end}} 如果pipeline的值其长度为0,不会有任何输出{{range pipeline}} T1 {{else}} T0 {{end}} 如果pipeline的值其长度为0,则会执行T0
with{{with pipeline}} T1 {{end}}
如果pipeline为empty不产生输出,否则将dot设为pipeline的值并执行T1,不修改外面的dot{{with pipeline}} T1 {{else}} T0 {{end}} 如果pipeline为empty,不改变dot并执行T0,否则dot设为pipeline的值并执行T1
预定义函数执行模板时,函数从两个函数字典中查找:首先是模板函数字典,然后是全局函数字典。一般不在模板内定义函数,而是使用Funcs方法添加函数到模板里。预定义的全局函数如下:
and 函数返回它的第一个empty参数或者最后一个参数; 就是说"and x y"等价于"if x then y else x";所有参数都会执行;or 返回第一个非empty参数或者最后一个参数; 亦即"or x y"等价于"if x then x else y";所有参数都会执行; not 返回它的单个参数的布尔值的否定len 返回它的参数的整数类型长度index 执行结果为第一个参数以剩下的参数为索引/键指向的值; 如"index x 1 2 3"返回x[1][2][3]的值;每个被索引的主体必须是数组、切片或者字典。 print 即fmt.Sprintprintf 即fmt.Sprintfprintln 即fmt.Sprintlnhtml 返回与其参数的文本表示形式等效的转义HTML。 这个函数在html/template中不可用。 urlquery 以适合嵌入到网址查询中的形式返回其参数的文本表示的转义值。 这个函数在html/template中不可用。 js 返回与其参数的文本表示形式等效的转义JavaScript。 call 执行结果是调用第一个参数的返回值,该参数必须是函数类型,其余参数作为调用该函数的参数; 如"call .X.Y 1 2"等价于go语言里的dot.X.Y(1, 2); 其中Y是函数类型的字段或者字典的值,或者其他类似情况; call的第一个参数的执行结果必须是函数类型的值(和预定义函数如print明显不同); 该函数类型值必须有1到2个返回值,如果有2个则后一个必须是error接口类型; 如果有2个返回值的方法返回的error非nil,模板执行会中断并返回给调用模板执行者该错误;
比较函数布尔函数会将任何类型的零值视为假,其余视为真。下面是定义为函数的二元比较运算的集合:
eq 如果arg1 == arg2则返回真ne 如果arg1 != arg2则返回真lt 如果arg1 < arg2则返回真le 如果arg1 <= arg2则返回真gt 如果arg1 > arg2则返回真ge 如果arg1 >= arg2则返回真为了简化多参数相等检测,eq(只有eq)可以接受2个或更多个参数,它会将第一个参数和其余参数依次比较,返回下式的结果:{{eq arg1 arg2 arg3}}比较函数只适用于基本类型(或重定义的基本类型,如”type Celsius float32”)。但是,整数和浮点数不能互相比较。# 自定义函数Go的模板支持自定义函数。func sayHello(w http.ResponseWriter, r *http.Request) {htmlByte, err := ioutil.ReadFile("./hello.tmpl")if err != nil {fmt.Println("read html failed, err:", err)return}// 自定义一个夸人的模板函数kua := func(arg string) (string, error) {return arg + "真帅", nil}// 采用链式操作在Parse之前调用Funcs添加自定义的kua函数tmpl, err := template.New("hello").Funcs(template.FuncMap{"kua": kua}).Parse(string(htmlByte))if err != nil {fmt.Println("create template failed, err:", err)return}user := UserInfo{Name: "小王子",Gender: "男",Age: 18,}// 使用user渲染模板,并将结果写入wtmpl.Execute(w, user)}我们可以在模板文件hello.tmpl中按照如下方式使用我们自定义的kua函数了。{{kua .Name}}# 嵌套template我们可以在template中嵌套其他的template。这个template可以是单独的文件,也可以是通过define定义的template。 注意:在解析模板时,被嵌套的模板一定要在后面解析,例如上面的示例中t.tmpl模板中嵌套了ul.tmpl,所以ul.tmpl要在t.tmpl后进行解析。
block{{block "name" pipeline}} T1 {{end}}block是定义模板{{define "name"}} T1 {{end}}和执行{{template "name" pipeline}}缩写,典型的用法是定义一组根模板,然后通过在其中重新定义块模板进行自定义。定义一个根模板templates/base.tmpl,内容如下:<html lang="zh-CN"> Go Templates<div class="container-fluid"> {{block "content" . }}{{end}}然后定义一个templates/index.tmpl,”继承”base.tmpl:{{template "base.tmpl"}}{{define "content"}} Hello world!{{end}}然后使用template.ParseGlob按照正则匹配规则解析模板文件,然后通过ExecuteTemplate渲染指定的模板:func index(w http.ResponseWriter, r http.Request){tmpl, err := template.ParseGlob("templates/.tmpl")if err != nil {fmt.Println("create template failed, err:", err)return}err = tmpl.ExecuteTemplate(w, "index.tmpl", nil)if err != nil {fmt.Println("render template failed, err:", err)return}}
心得体会:这些语法又是死记硬背的东西,多练练手记得可能会快点,这是传统的,相比于gin框架中的渲染,我觉得会比较繁琐一点,gin框架语法简单功能强大,我才学了一点点,下篇文章在细说gin框架我学习的内容