Go语言标准库之html/template详解

Go语言标准库之html/template

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是指产生数据的操作。比如{{.}}、{{.Name}}等。Go的模板语法中支持使用管道符号|链接多个命令,用法和unix下的管道类似:|前面的命令会将运算结果(或返回值)传递给后一个命令的最后一个位置。

  • 并不是只有使用了|才是pipeline。Go的模板语法中,pipeline的概念是传递数据,只要能产生数据的,都是pipeline。

变量

在这里插入图片描述

  • 语法就是这样子哈,还是方便的。

移除空格

  • 就是跟trim函数差不多,去除前后的空格
{{- .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]的值;每个被索引的主体必须是数组、切片或者字典。
print即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则返回真
  • 用法跟上面的类似哈

在这里插入图片描述

  • 返回的是布尔类型的数值哈,返回值如下: 例如false 或者 true

在这里插入图片描述

  • 学完这些,感觉在面向数据动态绑定的时候,应该可以解决大部分的web方面的难点了。啊哈哈哈哈哈哈

这些只是预处理好的函数,但是呢,我们在实际开发中,所需要的函数是超级超级多的,那么我们就必须自己去建立函数拉,这个也是我们Template里面的重点要求掌握的哈!

自定义函数

  • 我们来举个例子

在这里插入图片描述

  • 这个时候就要分四步啦
    1. 先我们定义一个函数类型的变量,里面写好函数
    2. 然后获取模板对象,然后在这个对象里面进行注册函数,一定要在解析模板之前进行注册
    3. 解析模板
    4. 渲染模板

这就完成了一个自定义函数了,我们随便搞个函数,就问下别人吃了吗?
调用也是很方便的!!

在这里插入图片描述

  • 因为我们在通过FuncMap进行注册的时候,取名叫wen,所以我们直接wen + 一个spring类型的变量即可。
  • 这就是自定义哈,很简单吧。

好了,进行学习就到这里拉,大家也要加油哦!

加油!!!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木木不会

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值