Go Web 编程中的模板库应用指南(超详细)
如果你有过Web编程的经验,那么或多或少都听说过或者使用过模板。简而言之,模板是可用于创建动态内容的文本文件。例如,你有一个网站导航栏的模板,其中动态内容的一部分可能是根据当前用户是否登录显示登录还是退出按钮。
Go提供了两个模板库text/template和html/template。这两个模板库的使用方式是相同的,但是html/template包在渲染页面模板时会在后台进行一些编码以帮助防止造成代码注入(XSS攻击)。
因为两个模板库都使用相同的接口,因此本文中介绍的所有内容均可用于这两个程序包,但是大多数时候我们都会使用html/template程序包来生成HTML代码段。
模板文件的后缀名
模板文件可以使用.html或任何其他扩展名。但是通常我们将使用.gohtml扩展名来命名模板文件,因为编辑器通常使用它来表示你想要高亮GoHTML模板语法。Atom和SublimeText等编辑器都具有Go插件,来默认识别此扩展名。
模板语法
我们先来创建一个简单的模板文件test.gohtml:
GoWeb {{.}}
{{和}}中间的半角句号.它代表模板对象执行Execute(w,data)传入模板的数据,它是顶级作用域范围内的,根据传入的数据不同渲染不同的内容。.可以代表Go语言中的任何类型,如结构体、Map等。
在写模板的时候,会经常用到.。比如{{.}}、{{len.}}、{{.Name}}、{{$x.Name}}
{{和}}包裹的内容统称为action,分为两种类型:
数据求值(dataevaluations)
控制结构(controlstructures)
action求值的结果会直接复制到模板中,控制结构和我们写Go程序差不多,也是条件语句、循环语句、变量、函数调用等等...模板中的action并不多,我们一个一个看。
注释
{{/*comment*/}}
裁剪空字符
注意裁剪的是替换内容前面或者后面的空字符,你可以理解成模板中{{前面或}}后面的空字符(包括换行符、制表符、空格等)。
//裁剪content前后的空字符
{{-content-}}
//裁剪content前面的空字符
{{-content}}
//裁剪content后面的空字符
{{content-}}
文本输出
{{pipeline}}
pipeline代表的数据会产生与调用fmt.Print函数类似的输出,例如整数类型的3会转换成字符串"3"输出。
条件语句
{{ifpipeline}}T1{{end}}
{{ifpipeline}}T1{{else}}T0{{end}}
{{ifpipeline}}T1{{elseifpipeline}}T0{{end}}
//上面的语法其实是下面的简写
{{ifpipeline}}T1{{else}}{{ifpipeline}}T0{{end}}{{end}}
{{ifpipeline}}T1{{elseifpipeline}}T2{{else}}T0{{end}}
如果pipeline的值为空,不会输出T1,除此之外T1都会被输出。
空值有false、0、nil空字符串""(长度为0的字符串)。
循环语句
{{rangepipeline}}T1{{end}}
//这个else比较有意思,如果pipeline的长度为0则输出else中的内容
{{rangepipeline}}T1{{else}}T0{{end}}
//获取容器的下标
{{range$index,$value:=pipeline}}T1{{end}}
循环语句中的pipeline的值必须是数组、切片、字典和通道中的一种,即可迭代类型的值,根据值的长度输出多个T1。
define
{{define"name"}}T{{end}}
定义命名为name的模板。
template
{{template"name"}}
{{template"name"pipeline}}
第一种是直接执行名为name的模板,模板的全局数据对象.设置为nil。第二种是点.设置为pipeline的值,并执行名为name的模板。
block
{{block"name"pipeline}}T1{{end}}
block的语义是如果有命名为name的模板,就引用过来执行,如果没有命名为name的模板,就是执行自己定义的内容。换句话说,block可以认为是设置一个默认模板。
with
{{withpipeline}}T1{{end}}
//如果pipeline是空值则输出T0
{{withpipeline}}T1{{else}}T0{{end}}
{{witharg}}
.//此时.就是arg
{{end}}
with创建一个新的上下文环境,在此环境中的.与外面的.无关。
对于第一种格式,当pipeline不为0值的时候,点.设置为pipeline运算的值,否则跳过。对于第二种格式,当pipeline为0值时,执行else语句块,否则.设置为pipeline运算的值,并执行T1。
例如:
{{with.Person}}{{.Name}}{{end}}
在这个with块中.Name实际上引用的是全局数据对象的.Person.Name。
实践练习:课程花名册页面
了解完模板语法后,接下来让我们在http_demo项目中结合BootStrap创建一个简单的模板,来展示服务器如何把数据传递给模板、渲染HTML页面,把页面响应返回给客户端。
我们创建一个用来展示大学物理课程的花名册(授课老师和上课学生)
创建页面模板
首先在我们的项目添加一个views目录用于存放模板文件,在创建三个模板文件分别是:
layout.gohtml用于存放页面的整体布局。
BootstrapTemplatePageforGoWebProgramming {{template"nav".}} {{template"content".}}