4、Go Gin HTML 模板渲染、静态文件加载

HTML 模板渲染

一、全部模板放在一个目录里面的配置方法

 1、目录结构

2、首先在项目根目录新建 templates 文件夹,然后在文件夹中新建 对应的index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>这是一个 html 模板</h1>
<h3>{{.title}}</h3>
</body>
</html>

3、单个目录模板代码案例 

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

func main() {
	//初始化路由
	r := gin.Default()
	//加载templates中所有模板文件,注意:一定要在使用模板之前加载
	r.LoadHTMLGlob("templates/*")
	//r.LoadHTMLFiles("templates/xxx.html", "templates/xxx.html")

	//http: //127.0.0.1:8080
	r.GET("/", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.html", gin.H{
			"title": "index页面-前台页面",
		})
	})

	//http://127.0.0.1:8080/index
	r.GET("/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.html", map[string]interface{}{
			"title": "index页面-前台页面",
		})
	})
	r.Run(":8080")
}

 二、模板放在不同目录里面的配置方法

 1、目录结构

2、在不同目录下创建同名字的html文件

注意:定义模板的时候需要通过 define 定义名称 

 admin/index.html

<!-- 相当于给模板定义一个名字 define end 成对出现-->
{{ define "admin/index.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>后台模板</h1>
<h3>{{.title}}</h3>
</body>
</html>
{{ end }}

 default/index.html 

<!-- 相当于给模板定义一个名字 define end 成对出现-->
{{ define "default/index.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>前台模板</h1>
<h3>{{.title}}</h3>
</body>
</html>
{{end}}

 3、单个目录模板代码案例 

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
	"os"
	"path/filepath"
	"strings"
)

func main() {
	// 加载引擎
	router := gin.Default()

	//方法一
	// 加载模板
	// 如果模板在多级目录里面的话需要这样配置 r.LoadHTMLGlob("templates/**/**/*") /**表示目录
	//router.LoadHTMLGlob("templates/**/*")

	//方法二
	//加载templates中所有模板文件, 使用不同目录下名称相同的模板,注意:一定要放在配置路由之前才得行
	//如果模板在多级目录里面的话需要这样配置 r.LoadHTMLGlob("templates/**/**/*") /** 表示目录
	//LoadHTMLGlob只能加载同一层级的文件
	//比如说使用router.LoadHTMLFile("/templates/**/*"),就只能加载/templates/admin/或者/templates/order/下面的文件
	//解决办法就是通过filepath.Walk来搜索/templates下的以.html结尾的文件,把这些html文件都加载一个数组中,然后用LoadHTMLFiles加载
	//r.LoadHTMLGlob("templates/**/*")
	var files []string
	filepath.Walk("./templates", func(path string, info os.FileInfo, err error) error {
		if strings.HasSuffix(path, ".html") {
			files = append(files, path)
		}
		return nil
	})
	router.LoadHTMLFiles(files...)

	// http://127.0.0.1:8080/default
	router.GET("/default", func(c *gin.Context) {
		c.HTML(http.StatusOK, "default/index.html", gin.H{
			"title": "前台首页",
		})
	})

	// http://127.0.0.1:8080/admin
	router.GET("/admin", func(c *gin.Context) {
		c.HTML(http.StatusOK, "admin/index.html", gin.H{
			"title": "后台首页",
		})
	})
	router.Run(":8080")
}

三、静态文件及模板 

1、代码结构

2、完整代码

admin/index.html
<!-- 相当于给模板定义一个名字, define end 必须成对出现 -->
{{ define "admin/index.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>后台首页</title>
</head>
<body>
<h2>{{.title}}</h2>
</body>
</html>
{{ end }}
admin/news.html 
{{ define "admin/news.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>后台新闻详情</title>
</head>
<body>
<h2>{{.title}}</h2>
<h3>{{.news.Title}}</h3>
<h4>{{.news.Content}}</h4>
</body>
</html>
{{ end }}
 default/index.html
<!-- 相当于给模板定义一个名字, define end 必须成对出现 -->
{{ define "default/index.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="/static/css/base.css">
    <title>这是一个简单的页面</title>
</head>
<body>
{{ template "public/page_header.html" .}}
<h2>{{.title}}</h2>
<img src="/static/images/header.jpg">
<!-- 定义变量 把后台的变量赋值给$t -->
{{ $t := .title}}
<!-- 显示$t -->
<h4> {{ $t }}</h4>
<!-- if判断 -->
{{if gt .score 90}}
<div>优秀</div>
<br/>
{{else if gt .score 80}}
<div>良好</div>
<br/>
{{else if gt .score 70}}
<div>可以</div>
<br/>
{{ else }}
<div>合格</div>
<br/>
{{end}}
<!-- 循环数据 -->
<ul>
    <!-- 循环切片 -->
    {{range $k, $v := .hobby}}
    <li>{{$k}} => {{$v}}</li>
    {{end}}
</ul>
<ul>
    <!-- 循环结构体 -->
    {{range $k, $v := .newList}}
    <li>{{$k}} => {{$v.Title}} --- {{$v.Content}}</li>
    {{end}}
</ul>
<ul>
    <!-- 循环空数组/切片 判断 -->
    {{range $k, $v := .testSlice}}
    <li>{{$k}} => {{$v.Title}} --- {{$v.Content}}</li>
    {{else}}
    <li>空数据</li>
    {{end}}
</ul>
<ul>
    <!-- with 解析结构体-->
    {{with .news}}
    <li>{{.Title}} => {{.Content}}</li>
    {{end}}
</ul>
<h4>
    <!--预定义函数 -->
    {{.title}}的长度为{{len .title}}
</h4>
<h4>
    <!--自定义函数 -->
    {{UnixToTime .date}}
    <br>
    {{Println .title "--------------"}}
    <br>
    {{Println "~~~~~~~~~~~" .news.Title}}
    <br>
    {{Println .title .news.Title}}
</h4>
<!-- 嵌套 template -->
{{ template "public/page_footer.html" .}}
</body>
</html>
{{end}}
 default/news.html
<!-- 相当于给模板定义一个名字, define end 必须成对出现 -->
{{ define "default/news.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>news</title>
</head>
<body>
{{ template "public/page_header.html" .}}

<link rel="stylesheet" href="static/css/base.css">
<h2>{{.title}}</h2>
<h4>
    {{.news.Title}}
    <br>
    {{.news.Content}}
</h4>
{{ template "public/page_footer.html" .}}
</body>
</html>
{{ end }}
 public/page_header.html
<!-- 相当于给模板定义一个名字, define end 必须成对出现 -->
{{ define "public/page_header.html" }}
<h1>
  公共的 --- {{.title}}
</h1>
{{end}}

  public/page_footer.html

<!-- 相当于给模板定义一个名字, define end 必须成对出现 -->
{{ define "public/page_footer.html" }}
<h4>
    公共的底部
</h4>
{{end}}
 go代码
package main

import (
	"github.com/gin-gonic/gin"
	"html/template"
	"net/http"
	"time"
)

type Article struct {
	Title   string `json:"title"`
	Content string `json:"
"`
}

// UnixToTime 时间戳转换成日期函数
func UnixToTime(timestamp int) string {
	t := time.Unix(int64(timestamp), 0)
	return t.Format("2006-01-02 15:04:05")
}

func Println(str1 string, str2 string) string {
	return str1 + str2
}

func main() {
	//初始化路由
	r := gin.Default()
	//自定义模板函数,必须在r.LoadHTMLGlob前面
	r.SetFuncMap(template.FuncMap{
		"UnixToTime": UnixToTime, //注册模板函数
		"Println":    Println,
	})
	//加载templates中所有模板文件, 使用不同目录下名称相同的模板,注意:一定要放在配置路由之前才得行
	r.LoadHTMLGlob("templates/**/*")
	//配置静态web目录 第一个参数表示路由,第二个参数表示映射的目录
	r.Static("/static", "./static")

	//配置路由
	//前台路由
	r.GET("/", func(c *gin.Context) {
		//渲染模板文件
		c.HTML(http.StatusOK, "default/index.html", gin.H{
			"title": "这是一个简单的页面",
			"score": 88,
			"hobby": []string{"吃饭", "睡觉", "打豆豆"}, // 切片
			"newList": []interface{}{ // 接口
				&Article{
					Title:   "新闻标题1",
					Content: "新闻内容1",
				},
				&Article{
					Title:   "新闻标题2",
					Content: "新闻内容2",
				},
			},
			"testSlice": []string{}, // 空数组/空切片
			"news": &Article{ // 结构体
				Title:   "新闻标题3",
				Content: "新闻内容3",
			},
			"date": 1714115969,
		})
	})
	r.GET("/news", func(c *gin.Context) {
		news := &Article{
			Title:   "新闻标题",
			Content: "新闻内容",
		}
		c.HTML(http.StatusOK, "default/news.html", gin.H{
			"title": "新闻详情",
			"news":  news,
		})
	})

	//后台路由
	r.GET("/admin", func(c *gin.Context) {
		//渲染模板文件
		c.HTML(http.StatusOK, "admin/index.html", gin.H{
			"title": "后台首页",
		})
	})
	r.GET("/admin/news", func(c *gin.Context) {
		news := &Article{
			Title:   "后台新闻标题",
			Content: "后台新闻内容",
		}
		c.HTML(http.StatusOK, "admin/news.html", gin.H{
			"title": "后台新闻详情",
			"news":  news,
		})
	})
	r.Run() // 启动一个web服务
}

  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值