官方文档里面也给了详细的解释哈,有兴趣可以看看哈。html/template包实现了数据驱动的模板,用于生成可防止代码注入的安全的HTML内容。
它提供了和text/template包相同的接口,Go语言中输出HTML的场景都应使用html/template这个包。
模板引擎的使用
我们用这个一般三步走,定义、解析、渲染
定义模板文件
这个定义一个html文件即可,后缀名成可以设定为 tmpl 或者 tpl ,不过我们一般使用tmpl
作为模板文件后缀。
模板文件解析
上面定义好了模板文件之后,可以使用下面的常用方法去解析模板文件,得到模板对象:func (t *Template) Parse(src string) (*Template, error)
func ParseFiles(filenames ...string) (*Template, error)
func ParseGlob(pattern string) (*Template, error)
三种方式都可以实现,待会我们来举个简单的例子试试
模板渲染
func (t *Template) Execute(wr io.Writer, data interface{}) error
func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error
我们通过execute函数把数据放入到模板文件里面去
模板语法
这里我们要说一下这个模板的语法哈。
{{.}} ,里面的这个点,就是传入的对象。例如:模板语法都包含在 {{和}} 中间,其中 {{.}} 中的点表示当前对象。
name := "张三"
err = t.Execute(w,name)
这样子, 括号里面的点就表示张三。可以直接放入到模板文件里面去动态的显示。这里面的模板类似于Java里面的Thymeleaf
,只不过语法不一样
当然,除了基本类型,还可以设置结构体,或者map。来看看结构体的
u1 := User{
Name:"小公主",
Gender:"女",
Age:16,
}
err = t.Execute(w,u1)
这样也可以,取数据的时候通过 .Name
.Age
.Gender
的形式进行读取数据即可这个主意要首字母大写哈,因为结构体要对外开放权限哦
然后我们来看看map,来做个完整的例子吧
package main
import (
"fmt"
"html/template"
"net/http"
)
type User struct {
Name string
Gender string
Age int
}
func index(w http.ResponseWriter, r *http.Request) {
// 解析模板
t, err := template.ParseFiles("Template_test/index.tmpl")
if err != nil {
fmt.Println("Parse template failed! err:",err)
return
}
// 渲染模板
u1 := User{
Name:"小公主",
Gender:"女",
Age:16,
}
m1 := map[string]interface{}{
"name":"小皇子",
"gender":"男",
"age" : 18,
}
err = t.Execute(w,map[string]interface{}{
"u1":u1,
"m1":m1,
})
if err != nil {
fmt.Println("render template failed,err : ",err)
return
}
}
func main() {
http.HandleFunc("/index",index)
err := http.ListenAndServe(":9090",nil)
if err != nil {
fmt.Println("HTTP server start failed! err : ", err)
return
}
}
这里我们可以看到哈,我们将一个map数据和一个结构体数据统一的放入到一个map里面,然后将这个全部的数据统一的返回给模板。这个稍微比Java麻烦一点哈,一次只能返回一个大的map,啊哈哈哈哈哈不过问题也不大。然后我们来看看模板
我们可以看到哈,模板的引用也是非常的简单。值得一说的是要注意大小写哈,map里面的因为直接就是key/value的形式,所以不用首字母大写。然后我们来看看效果。
完美实现哈,现在我们就学会了数据的引用和传输了。
模板的注释
{{/* 需要注释的内容 */}}注释,执行时会忽略。可以多行。注释不能嵌套,并且必须紧贴分界符始止。我最讨厌的就是不写注释的同学了,啊哈哈哈哈哈
pipeline
并不是只有使用了|才是pipeline。Go的模板语法中,pipeline的概念是传递数据,只要能产生数据的,都是pipeline。 变量 语法就是这样子哈,还是方便的。 移除空格 就是跟trim函数差不多,去除前后的空格pipeline是指产生数据的 *** 作。比如{{.}}、{{.Name}}等。Go的模板语法中支持使用管道符号|链接多个命令,用法和unix下的管道类似:|前面的命令会将运算结果(或返回值)传递给后一个命令的最后一个位置。
{{- .Name -}}
注意:- 要紧挨{{和}},同时与模板值之间需要使用空格分隔。
条件判断语句 Go模板语法中的条件判断有以下几种:{{if pipeline}} T1 {{end}}
{{if pipeline}} T1 {{else}} T0 {{end}}
{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
我们来简单演示一下
这里我们比较一下两个参数的,i是否小于 200 ,lt是小于的意思哈,后面会说
结果就是这样哈,这就是if了,也是可以进行嵌套的哈,感兴趣的话,可以自己去尝试哈。
range循环遍历
这个就是将数据进行一个循环遍历输出的了,相当于for循环的样子Go的模板语法中使用range关键字进行遍历,有以下两种写法,其中pipeline的值必须是数组
、切片
、字典
或者通道
。
举个例子:
hobbyList := []string{
"篮球",
"足球",
"双色球",
}
我们将这个切片通过Execute函数传到模板上面去。然后对这个切片进行遍历输出
这里我们声明两个变量,分别来接受这个切片的索引和内容
展示效果,还行哈,css这块大家有兴趣自己去配置哈。
看下range的全部语法哈
{{range pipeline}} T1 {{end}}
如果pipeline的值其长度为0,不会有任何输出
{{range pipeline}} T1 {{else}} T0 {{end}}
如果pipeline的值其长度为0,则会执行T0。
with
帮忙省东西的,比如,前面我们写 .u1 和 .m1 这种,我们可以通过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]的值;每个被索引的主体必须是数组、切片或者字典。 |
即fmt.Sprint , printf和println同理 | |
html | 返回与其参数的文本表示形式等效的转义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则返回真 |
这些只是预处理好的函数,但是呢,我们在实际开发中,所需要的函数是超级超级多的,那么我们就必须自己去建立函数拉,这个也是我们Template里面的重点要求掌握的哈!
自定义函数 我们来举个例子 这个时候就要分四步啦1. 先我们定义一个函数类型的变量,里面写好函数
2. 然后获取模板对象,然后在这个对象里面进行注册函数,
一定要在解析模板之前进行注册
3. 解析模板
4. 渲染模板
这就完成了一个自定义函数了,我们随便搞个函数,就问下别人吃了吗?
调用也是很方便的!!
好了,进行学习就到这里拉,大家也要加油哦!
加油!!!欢迎分享,转载请注明来源:内存溢出
评论列表(0条)