go可以不需要第三方的模板, 它自己具有模板功能
首先需要模板文件(作为渲染页面):
index.html:
<html>
<head>
<title>this is a template</title>
</head>
<body>
<h1> name: {{.Name}}</h1> <!--语法是使用双花括号-->
<h1> age: {{.Age}}</h1> <!--点代表当前变量-->
<h1> {{.}}</h1> <!--这里传入的变量是结构体, 则点就相当于结构体变量-->
</body>
</html>
然后用一个go程序去填充模板中需要的数据:
import (
"fmt"
"text/template"
"os"
)
type Student struct {
Name string
Age int
}
func main() {
t, err := template.ParseFiles("index.html") // 解析模板文件(我这把它们放在同一个文件夹下, 使用相对路径)
if err != nil {
fmt.Println("parse template file failed: ", err)
return
}
p := Student{
Name : "张三",
Age : 24,
}
if err := t.Execute(os.Stdout, p); err != nil { // 将p数据传入t模板中, 最后将结果渲染到os.Stdout
fmt.Println("template excute failed: ", err)
}
}
将模板渲染到浏览器窗口:
其实主要就是修改template的Execute函数的参数
Execute(第一个参数是渲染的位置, 第二个是渲染用到的数据)
如果要渲染到浏览器窗口或一个文件中, 只需要修改第一个参数即可:
package main
import (
"fmt"
"text/template"
"net/http"
)
// 创建全局的模板变量
var myTemplate *template.Template
// 创建数据承载结构体
type Student struct {
Name string
Age int
}
/*hander函数*/
func templateHander(w http.ResponseWriter, r *http.Request) {
// panic处理
defer func(){
if x:=recover(); x!= nil {
return
}
}()
p := Student{
Name : "张三",
Age : 24,
}
if err := myTemplate.Execute(w, p); err != nil { // 写到浏览器窗口
fmt.Println("template excute failed: ", err)
}
}
// 加载模板
func initTemplate(filePath string) (err error){
myTemplate, err = template.ParseFiles(filePath) // 解析模板文件
if err != nil {
fmt.Println("parse template file failed: ", err)
return
}
return nil
}
func main() {
initTemplate("index.html") // 加载模板
http.HandleFunc("/", templateHander) // 加载handler函数
/*启动http服务器*/
err := http.ListenAndServe(":9000", nil)
if err != nil {
fmt.Println("start server failed: ", err)
}
}
模板if判断:
在渲染页面的时候, 可能会根据不同情况(登陆与否, 是否是会员等)做不同的展示
语法: {{if op a b}} ... {{else}} ... {{end}}
<html>
<head>
<title>this is a template</title>
</head>
<body>
{{if gt .Age 20}} <!--gt表示大于(此处表示 .Age > 20是否为真)-->
<h3>old man</h3>
{{else}}
<h3>young man</h3>
{{end}}
<h1> {{.}}</h1>
</body>
</html>
常用操作符:
not -- 非
and -- 与
or -- 或
eq -- 等于
ne -- 不等于
lt -- 小于
参数传入map:
如果Execute函数的第二个参数传入的是map, 则{{. xxx}}里面的点就表示map
var m = make(map[string]interface{})
m["name"] = "张三"
m["age"] = 20
if err := myTemplate.Execute(w, m); err != nil { // 将第二个参数直接换成map
fmt.Println("template excute failed: ", err)
}
<body>
{{if eq .name "张三"}}
<h3>eq</h3>
{{else}}
<h3>ne</h3>
{{end}}
<h1> {{.}}</h1>
</body>
with...end简化:
语法: {{with}}...{{end}}
用于简化操作, 如果传入的数据(即点表示的内容) 比较复杂
而只需要使用其中的一部分内容, 则可以使用with分解
with...end之间的点就表示分解后的内容
<html>
<head>
<title>this is a template</title>
</head>
<body>
{{with.name}}
<h3>name: {{.}}</h3> <!--with...end之间的点表示使用with分解获取到的内容-->
{{end}}
<h1> {{.}}</h1> <!---with...end外面的点还是最初传入的内容-->
</body>
</html>
name: 张三
map[name:张三 age:20]
range循环:
语法: {{range .}} ... {{end}}
这这上面with...end类似, range ... end之间的点则表示循环到的内容(变量), 即它也包含分解
<html>
<head>
<title>this is a template</title>
</head>
<body>
<table border="1">
{{range .}}
<tr>
<td>Name: {{.Name}}</td>
<td>Age : {{.Age}}</td>
<td>Score: {{.Score}}</td>
</tr>
{{end}}
</table>
</body>
</html>
Name: 张三 | Age : 24 | Score: 88 |
Name: 李四 | Age : 22 | Score: 78 |
Name: 王五 | Age : 25 | Score: 98 |
模板大概就是if判断, range循环, with简化变量, 配合操作符使用