HTML模板渲染--绑定后台数据
全部模板放在一个目录里的配置方法
1.首先在项目根目录新建templates文件夹(模板文件夹),然后在文件夹中新建html文件。
如图,index.html文件与news.html文件均放在templates文件夹里
2.在main文件中配置模板目录,加载模板
r.LoadHTMLGlob("templates/*")
3.配置路由
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
type Article struct {
Title string
Content string
}
func main() {
r := gin.Default()
//配置模板目录,加载模板
r.LoadHTMLGlob("templates/*")
r.GET("/", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", gin.H{
"title": "首页",
})
})
r.GET("/news", func(c *gin.Context) {
news := &Article{
Title: "新闻标题",
Content: "新闻详情",
}
c.HTML(http.StatusOK, "news.html", gin.H{
"title": "新闻页面",
"news": news,
})
})
r.Run(":8080")
}
4.在HTML文件里编写页面展示的内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>{{.title}}<h2> //index.html
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>{{.title}}</h2>
<h5>{{.news.Title}}</h5>
<h5>{{.news.Content}}</h5>
//news.html
</body>
</html>
模板放在不同目录里面的配置方法
当项目比较大时,需对模板进行分组,如下图这样:
此时,需更改一些代码使之能够正常运行
1.加载模板代码
r.LoadHTMLGlob("templates/**/*") // /**表示一个目录
2.Gin 框架中如果不同目录下面有同名模板的话我们需要使用下面方法加载模板
注意:定义模板的时候需要通过 define 定义名称,相当于给模板定义一个名字 define end 成对出现
{{ define "default/news.html"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>{{.title}}</h2>
<h5>{{.news.Title}}</h5>
<h5>{{.news.Content}}</h5>
</body>
</html>
{{end}}
其他三个也使用define end定义一个名字
3.在main.go文件中将所需渲染的目录标明
r.GET("/default", func(c *gin.Context) {
c.HTML(http.StatusOK, "default/index.html", gin.H{
"title": "首页",
})//标明所渲染页面为default目录下的index页面
})
Gin模板基本语法
1、{{.}}输出数据
模板语法都包含在{{和}}中间,其中{{.}}中的点表示当前对象。
2、注释
{{/* a comment */}} //多行注释
3、变量
我们还可以在模板中声明变量,用来保存传入模板的数据或其他语句生成的结果。
//定义变量
{{$obj := .title}}
{{$obj}}
4、比较函数
布尔函数会将任何类型的零值视为假,其余视为真。
下面是定义为函数的二元比较运算的集合:
| eq | 如果 arg1 == arg2 则返回真 |
| ne | 如果 arg1 != arg2 则返回真 |
| lt | 如果 arg1 < arg2 则返回真 |
| le | 如果 arg1 <= arg2 则返回真 |
| gt | 如果 arg1 > arg2 则返回真 |
| ge | 如果 arg1 >= arg2 则返回真 |
5、条件判断
{{if gt .score 90}}
优秀
{{else if gt .score 60}}
及格
{{else}}
不及格
{{end}}
6、range--循环遍历
{{range $key,$value := hobby}}
<li>{{$key}}---{{$value}}<li>
{{end}}
7、with--解构结构体
user := UserInfo{
Name: "张三",
Gender: "男",
Age: 18,
}
router.GET("/", func(c *gin.Context) {
c.HTML(http.StatusOK, "default/index.html",map[string]interface{}{
"user": user,
})
})
//以前要输出数据:
<p>{{.user.name}}<p>
//现在输出数据
{{with .user}}
<h4>姓名:{{.Name}}</h4>
<h4>性别:{{.user.Gender}}</h4>
<h4>年龄:{{.Age}}</h4>
{{end}}
8、预定义函数(了解)
执行模板时,函数从两个函数字典中查找:首先是模板函数字典,然后是全局函数字典。一般不在模板内定义函数,而是使用 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
即 fmt.Sprintf
println
即 fmt.Sprintln
html
返回与其参数的文本表示形式等效的转义 HTML。
这个函数在 html/template 中不可用。
urlquery
以适合嵌入到网址查询中的形式返回其参数的文本表示的转义值。
这个函数在 html/template 中不可用。
js
返回与其参数的文本表示形式等效的转义 JavaScript。
9、自定义模板函数
package main
import (
"fmt"
"net/http"
"text/template"
"time"
"github.com/gin-gonic/gin"
)
// 时间戳转换成日期
func UnixToTime(timestamp int) string {
fmt.Println(timestamp)
t := time.Unix(int64(timestamp), 0)
return t.Format("2006-01-02 15:04:05")
}
func main() {
r := gin.Default()
//自定义模板函数 注意要把这个函数放在加载模板前
r.SetFuncMap(template.FuncMap{
"UnixToTime": UnixToTime,
})
//配置模板目录,加载模板
r.LoadHTMLGlob("templates/**/*") // /**表示一个目录
//前台
r.GET("/default", func(c *gin.Context) {
c.HTML(http.StatusOK, "default/index.html", gin.H{
"title": "首页",
"date": 1692951341,
})
})
r.Run(":8080")
}
前台调用自定义函数
{{UnixToTime .date}}
10、嵌套template
1、新建templates/deafult/page_header.html
{{define "public/page_header.html"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h4>这是一个标题</h4>
</body>
</html>
{{end}}
2、外部引入
注意:
1、引入的名字为 page_header.html 中定义的名字
2、引入的时候注意最后的点(.)
{{ define "default/index.html"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{{template "public/page_header.html" .}} //引入一个公共部分
<h2>{{.title}}<h2>
<br>
{{UnixToTime .date}}
</body>
</html>
{{end}}