模板文件默认存放在beego项目下的views目录下,如果我们想要将模板文件换到另一个目录时该如何操作那?
一、指定模板文件目录的方法
方法一:
在main.go文件里,beego.Run()上方添加:beego.SetViewsPath("newpath"),指定模板文件路径。
方法二:
在配置文件里设置:viewspath = "newpath",指定模板文件路径。
二、添加模板文件支持其他结尾与管理模板渲染
2.1、添加模板文件支持其他结尾的模板
beego里默认支持 “.tpl和.html” 模板文件
设置模板支持其他后缀名:beego.AddTemplateExt("后缀名")
2.2、管理模板渲染
如果我们只是用beego写接口,不需要渲染模板(如果既有接口又有模板就打开自动渲染),关闭模板渲染的两种方法。
(1)在配置文件里管理渲染
autorender = false // 在配置文件关闭自动渲染
(2)在main.go里管理渲染
再main.go文件里beego.Run()上方添加如下配置关闭自动渲染: beego.BConfig.WebConfig.AutoRender = false
三、模板渲染
后端的数据想在前端模板文件里展示时需要将后端的数据传递给模板文件,然后再模板文件里使用特定的语法展示出来。
3.1、模板语法
(1)go统一使用 {{ 和 }} 作为左右标签,也可以用下面的方法修改为其他的符号(不建议修改),修改后会有问题。
beego.BConfig.WebConfig.TemplateLeft = "((" beego.BConfig.WebConfig.TemplateRight = "))"
(2)使用 . 来访问当前位置的上下文,示例如下
示例一:直接调用.name变量时.的上一级是后端传过来的数据 {{.name}} 示例二:循环时的.与循环里的. {{for range .array}} --> 循环时.的上一级是后端传过来的数据 {{.}} --> 循环里的.的上一级是外层循环的. {{end}}
(3)使用 $ 来引用当前模板根级的上下文,示例如下
{{range $i,$v := .array}} --> 循环时时.的上一级是后端传过来的数据,此时$的上级是.($的作用域只限于当前模板) {{$i}} --> 此时$的上级是外层循环的$ {{$v}} {{end}}
(4)使用 "$." 引用模板中的根级上下文
{{for range .array}} --> 循环时.的上级是后端传过来的数据 {{.}} --> 循环里.的上级是外层循环的. {{$.name}} --> $.的上级是后端传过来的name数据("$."的上级直接是后端传过来的数据,也叫根级数据。) {{end}}
3.2、beego模板里支持的符号
(1)字符串:beego模板里在双引号里的是字符串类型的数据
{{"string"}}
(2)转译符:beego模板字符串里的单个\起到转译的功能
{{"\\string"}} --> 展示的结果是:\string,也就是说单个\在模板字符串里是转译的意思。
(3)原生字符串:原生字符串用``包着,``里面是啥得到的结果就是啥,``里面不支持转译
{{`\\string`}} --> 反引号里的是原生字符串,反引号里不支持转义符号(即写的啥展示的就是啥),展示结果为:\\string
(4)字节类型:在单引号里的值是字节类型(ascll码)
{{'a'}} --> 单引号里的是字节类型(ascll码),a对应的ascll码的值为97,所以展示结果是97
(5)nil(空):beego模板里nil也表示空类型,nil类型模板不能直接渲染,需要借助模板自带的函数print实现渲染,使用方法如下
{{print nil}} --> 展示结果是:<nil>,nil类型在模板上展示需要借助print方法(如果直接写{{nil}}会报错:nil is not a command)
(6)pipeline(管道):将管道前面的数据交给管道后面的方法处理,类似于linux下的管道(|)
{{"uxuan.cc"|len}} --> pipeline(类似linux的管道),将前面的数据交给后面的方法处理 注意:当出现如下情况时,pipeline认定为空: 1.false 或 0 2.nil的指针或interface 3.长度为0的array、slice、map、string
3.3、指定模板文件、传数据给模板与模板渲染数据
(1)往模板里传数据,示例如下(如果不指定模板文件只传数据时启动程序时会报错):
func (c *IndexController) Get() { c.Data["Email"] = "admin@uxuan.cc" // 传字符串类型的数据 c.TplName = "index.html" // 指定模板 }
(2)模板文件里渲染字符串类型数据,示例如下
<p>Email: {{.Email}}</p>
四、其他类型的数据传递与模板渲染
4.1、后端传递数据
func (c *TestController) Get() { // 1.字符串渲染 c.Data["Website"] = "uxuan.cc" c.Data["Email"] = "dream@uxuan.cc" // 2.结构体渲染 user := UserStruct{ Id: 1, Name: "Dream", Age: 22, } c.Data["User"] = user // 3.数组渲染 var arrs = [5]int{9,7,8,5,3} c.Data["Arrs"] = arrs // 4.数组结构体渲染 arr_struct := [4]UserStruct{{Id: 1, Name: "Dream", Age: 22,}, {Id: 2, Name: "Dream", Age: 22,},{Id: 3, Name: "Dream", Age: 22,}, {Id: 4, Name: "Dream", Age: 22,}} c.Data["ArrStruct"] = arr_struct // 5.map渲染 testMap := map[string]string{"Name": "Dream", "Class": "Go语言开发", "Sex": "man",} c.Data["maps"] = testMap // 6.结构体map渲染 structMap := make(map[int]UserStruct) structMap[1] = UserStruct{Id: 1, Name: "Dream", Age: 22} structMap[2] = UserStruct{Id: 2, Name: "Dream2", Age: 22} structMap[3] = UserStruct{Id: 3, Name: "Dream3", Age: 22} c.Data["MapStruct"] = structMap // 7.切片渲染 var slices = []int{1,3,5,7,9} c.Data["Slices"] = slices c.TplName = "index.html" }
4.2、模板里渲染数据
<!DOCTYPE html> <html> <head> <title>Beego</title> </head> <body> <!--结构体渲染--> <h1>数据渲染</h1> <h3>1.字符串渲染</h3> <p>网址: {{.Website}}</p> <p>邮箱: {{.Email}}</p> <br> <h3>2.结构体渲染</h3> <p>ID:{{.User.Id}}</p> <p>用户名:{{.User.Name}}</p> <p>年龄:{{.User.Age}}</p> <br> <h3>3.数组渲染</h3> <h5>3.1: 循环数组 - 方法1</h5> {{range .Arrs}} {{.}} {{end}} <h5>3.2: 循环数组 - 方法2</h5> {{range $i, $v := .Arrs}} index: {{$i}} value: {{$v}} {{end}} <br> <h3>4.数组结构体渲染</h3> <h5>4.1: 循环数组结构体方法1</h5> {{range .ArrStruct}} {{.Id}} {{.Name}} {{.Age}} {{end}} <br> <h5>4.2: 循环数组结构体方法2</h5> {{range $v := .ArrStruct}} <!-- 留$i, $v时:i是下标,v是变量值,留$v时默认v获取的是变量值 --> {{$v.Id}} {{$v.Name}} {{$v.Age}} {{end}} <br> <h3>5.map渲染</h3> <h5>5.1: map单个字段渲染</h5> {{.maps.Name}} {{.maps.Class}} {{.maps.Sex}} <br> <h5>5.2: 循环方式1循环map</h5> {{range .maps}} {{.}} {{end}} <br> <h5>5.3: 循环方式2循环map</h5> {{range $k,$v := .maps}} {{$k}}: {{$v}}<br> {{end}} <br> <h3>6.结构体map渲染</h3> {{range $k, $v := .MapStruct}} {{$k}}: {{$v}} - ID: {{$v.Id}}, Name: {{$v.Name}}, Age: {{$v.Age}}<br> {{end}} <br> <h3>7.切片渲染</h3> <h5>7.1: 循环切片1</h5> {{range .Slices}} {{.}} {{end}} <br> <h5>7.2: 循环切片2</h5> {{range $i, $v := .Slices}} index: {{$i}} value: {{$v}} <br> {{end}} </body> </html>
4.3、展示结果
五、模板里的基本逻辑
5.1、模板里判断 ”大于、小于、等于、大于等于、小于等于“ 方法
beego模板里没有><=等方法,需要使用下面的方法判断大小。
- eq:等于
- ne:不等于
- gt:大于
- ge:大于等于
- lt:小于
- le:小于等于
使用方法示例:
1、等于判断 {{eq 3 5}} --> 结果为false(因为3不等于5,表达式不成立) 2、不等于判断 {{ne 3 5}} --> 结果为true(因为3不等于5,表达式成立) 3、多个参数之间判断 {{eq 3 4 5 3}} --> 结果是true(多个参数判断时,每两个参数都会判断一次,只要有两个参数相等表达式就成立) {{eq 3 4 5 6}} --> 结果是false
5.2、模板里的if判断
示例一:进入某场馆需要年满十八岁,同时需要办理vip才可以进入,下面的两个判断实现了年满十八和是否是vip的判断:
{{if ge .age 18}} --> 判断后端传过来的数据age是否大于等于18,大于等18执行这里 年龄大于18周岁 {{if eq .is_vip 1}} --> 判断后端传过来的数据is_vip是不是等于1,等于1执行这里 欢迎光临,最贵的vip。 {{else}} --> 后端传过来的数据is_vip不等于1执行这里 欢迎光临,你还不是vip,请办理会员。 {{end}} --> 中间的if判断的结尾,每个if判断都需要有{{end}}结尾 {{else}} --> 后端传过来的数据age不大于等于18执行这里 年龄不满18周岁 {{end}} --> 第一个判断的结尾,每个if判断都需要有{{end}}结尾
5.3、range循环
示例一:
{{range .array}}
{{.}}
{{end}}
示例二:
{{range $i,$v := .array}}
{{$i}}
{{$v}}
{{end}}
示例三:range和else结合使用
{{range .array}} {{.}} {{else}} --> 如果range循环的数组是空的或者长度为0时就会执行{{else}}里的内容 <p>空的数组</p> {{end}}
5.4、with方法使用
方法一:
1、前面我们介绍的结构体类型渲染方法如下: {{.struct_data.Id}} {{.struct_data.Name}} {{.struct_data.Age}} 2、使用with方法渲染结构体: {{with .struct_data}} {{.Id}} {{.Name}} {{.Age}} {{end}}
方法二、with和else结合使用
{{with .name1}} {{.}} {{else}} --> 当前面的结果没有值时执行{{else}}里的操作 <p>没有这个属性值</p> {{end}}
5.5、template模板引用
在一个模板里引用另一个模板文件,示例如下:
示例一:引用模板文件
1.定义被引用的模板名字为:template1.html 2.在index.html里使用如下方法引用template1.html模板 {{template "template1.html" .}}
说明:
- template:固定语法
- "template1.html":引用的模板文件(这样写表示两个模板文件是同一级目录)
- . :上下文,后端传的数据只传入当前模板文件里了,被引用的模板文件如果需要获取上下文时第三个参数.就不能少,少了.被引用的模板文件就无法获取后端传过来的数据了。
示例二:使用define自定义模板格式,然后template引用模板格式
1.在同一文件里定义模板格式 {{define "ul_li"}} --> 定义的模板格式名字为:ul_li,定义的模板格式是不显示的 <ul><li>{{.name}}</li></ul> <ul><li>{{.age}}</li></ul> {{end}} 2.在同一文件里引用模板格式 {{template "ul_li" .}} --> 定义的模板格式需要用template引用时才会展示,三个参数和模板引用的参数一样