〇、前言 Gin框架是一个用于构建Web应用程序的轻量级Web框架,使用Go语言开发。它具有高性能、低内存占用和快速路由匹配的特点,旨在提供简单、快速的方式来开发可扩展的Web应用程序。
快速的性能:Gin框架采用了高性能的路由引擎,使请求路由匹配变得非常快速。
中间件支持:Gin框架支持中间件机制,允许你在请求处理过程中添加自定义的中间件,用于处理认证、日志记录、错误处理等功能。
路由组:Gin框架允许将路由按照逻辑组织成路由组,使代码结构更清晰,并且可以为不同的路由组添加不同的中间件。
请求参数解析:Gin框架提供了方便的方法来解析请求中的参数,包括查询字符串参数、表单参数、JSON参数等。
模板渲染:虽然Gin框架本身不提供模板引擎,但它与多种模板引擎库(如html/template、pongo2等)集成,使你能够方便地进行模板渲染。
错误处理:Gin框架提供了内置的错误处理机制,可以捕获和处理应用程序中的错误,并返回适当的错误响应。
 
总体而言,Gin框架是一个简单、轻量级但功能强大的Web框架,非常适合构建高性能、可扩展的Web应用程序。它在Go语言社区中得到广泛的认可,并被许多开发人员用于构建各种类型的Web应用程序。
一、html/template html/template是Go语言标准库中的一个包,用于生成和渲染HTML模板。它提供了一种安全且灵活的方式来生成HTML输出,支持模板继承、变量替换、条件语句、循环结构等功能。
html/template包的主要目标是防止常见的Web安全漏洞,如跨站脚本攻击(XSS)。它通过自动进行HTML转义和编码来确保生成的HTML是安全的,并防止恶意用户注入恶意代码。
使用html/template包可以将动态数据与静态HTML模板分离,使代码更易于维护和重用。你可以定义模板文件,然后将数据传递给模板进行渲染,最后生成最终的HTML输出。
(一)初次渲染 先创建一个名为 hello.tmpl的文件:
1 2 3 4 5 6 7 8 9 <!DOCTYPE html>"zh-CN" >
这里的{{.}}中的.就代表了我们要填充的东东,接着创建我们的main.go函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 package  mainimport  ("fmt" "html/template" "net/http" func  sayHello (w http.ResponseWriter, r *http.Request) "/Users/luliang/GoLand/gin_practice/chap1/hello.tmpl" )if  err != nil  {"http server failed:%V" , err)return "小王子!" )if  err != nil  {"http server failed:%V" , err)return func  main () "/hello" , sayHello)":9000" , nil )if  err != nil  {"http server failed:%V" , err)return 
使用html/template进行HTML模板渲染的一般步骤如下:
定义模板:hello.tmpl;
创建模板对象:
解析模板:
渲染模板:
 
在浏览器中输入:127.0.0.0:9000/hello就可以看到结果:hello, 小王子! 
(二)传入其它数据进行渲染 上次渲染,我们用的是这一句:err = t.Execute(w, "小王子!"),可以看到我们传入了一个字符串而已。这次我们打算传点稍微不同的其它数据。继续编写模板test.tmpl:
1 2 3 4 5 6 7 8 9 10 11 <!DOCTYPE html>"zh-CN" >
可以看到,我们的模板稍微复杂起来了!继续编写 main.go:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 package  mainimport  ("fmt" "html/template" "net/http" type  User struct  {string string  int func  sayHello (w http.ResponseWriter, r *http.Request) "小王子" ,"男" ,19 ,"/Users/luliang/GoLand/gin_practice/chap2/test.tmpl" )if  err != nil  {"ParseFiles failed:%V" , err)return if  err != nil  {return func  main () "/hello" , sayHello)":9000" , nil )if  err != nil  {"http server failed:%V" , err)return 
可以看到我们在里面定义了一个结构类型 User,传入了一个 User 对象 u1:err = t.Execute(w, u1)
1 2 3 4 5 type  User struct  {string string  int 
赶紧看看运行结果,可以看到结果符合预期:
姓名: 小王子
 
(三)定义函数参与渲染 定义我们的模板:f.tmpl:
1 2 3 4 5 6 7 8 9 <!DOCTYPE html>"zh-CN" >
可以看到,我们的模板里面有一个函数名字叫做 kua,没错,这就是我们要的函数。
编写main.go:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 package  mainimport  ("fmt" "html/template" "net/http" func  f (w http.ResponseWriter, r *http.Request) func (name string ) string , error ) {return  name + "太棒了!" , nil "f.tmpl" )"kua" : k,"/Users/luliang/GoLand/gin_practice/chap3/f.tmpl" )if  err != nil  {return "小王子" )if  err != nil  {return func  main () "/hello" , f)":9002" , nil )if  err != nil  {"http server failed:%V" , err)return 
可以看到,我用了一个关键语句将函数kua 关联到了模板:
1 2 3 t.Funcs(template.FuncMap{"kua" : k,
点击运行,可以看到结果:小王子太棒了! 
(四)c.HTML() 渲染 在Gin框架中,可以使用c.HTML()方法来进行HTML模板渲染。该方法接收HTTP状态码、模板名称和渲染所需的数据作为参数。
编写模板index.tmpl:
1 2 3 4 5 6 7 8 9 10 11 12 <!DOCTYPE html>"en" >"UTF-8" >"viewport"  content="width=device-width, initial-scale=1.0" >"X-UA-Compatible"  content="ie=edge" >
可以看到我们只需渲染传入对象的 title 值,编写 main.go:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package  mainimport  ("github.com/gin-gonic/gin" "net/http" func  main () "/Users/luliang/GoLand/gin_practice/chap4/index.tmpl" )"/index" , func (c *gin.Context) "index.tmpl" , gin.H{"title" : "你好,前端真是太有意思了!" ,":9091" )
首先,创建一个 gin.default()路由对象,然后给该对象载入已经写好的模板文件,之后就可以用 GET 函数进行请求了。
1 2 3 4 func  (group *RouterGroup) string , handlers ...HandlerFunc) IRoutes {return  group.handle(http.MethodGet, relativePath, handlers)
它说,GET 是router.Handle("GET", path, handlers)的一个捷径。再看看router.Handle("GET", path, handlers)是什么东西:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 func  (group *RouterGroup) string , handlers HandlersChain) IRoutes {return  group.returnObj()
原来就是做了一下中间处理,注册了一个新的请求句柄。它还说GET, POST, PUT, PATCH、DELETE 都有类似的捷径。之后在 handlers中放一个匿名函数:
1 2 3 4 5 func (c *gin.Context) "index.tmpl" , gin.H{"title" : "你好,前端真是太有意思了!" ,
这个函数就是用于渲染的函数。猜测c.HTML()依然是一个 shortcut:
1 2 3 4 5 6 7 func  (c *Context) int , name string , obj any) {
可以看到真正干活的还是 Render()。
点击运行,结果为:你好,前端真是太有意思了! 
(五)从多个模板中选择一个进行渲染 如果要渲染多个文件,该如何操作?比如我们通过输入不同的网站,服务器这时只需要选择不同的模板进行渲染就好。在这里创建了两个模板文件,users/index.tmpl:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 {{define "users/index.tmpl" }}"en" >"UTF-8" >"viewport"  content="width=device-width, initial-scale=1.0" >"X-UA-Compatible"  content="ie=edge" >
posts/index.tmpl:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 {{define "posts/index.tmpl" }}"en" >"UTF-8" >"viewport"  content="width=device-width, initial-scale=1.0" >"X-UA-Compatible"  content="ie=edge" >
这里使用了{{define "posts/index.tmpl"}}...{{end}}结构,对模板文件进行了命名。main.go:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package  mainimport  ("github.com/gin-gonic/gin" "html/template" "net/http" func  main () "/Users/luliang/GoLand/gin_practice/chap5/templates/**/*" )"/posts/index" , func (c *gin.Context) "posts/index.tmpl" , gin.H{"title" : "posts/index.tmpl" ,"/users/index" , func (c *gin.Context) "users/index.tmpl" , gin.H{"title" : "送你到百度!" ,":9091" )
我们在在浏览器地址栏输入http://127.0.0.1:9091/users/index可以得到:送你到百度!;而输入http://127.0.0.1:9091/posts/index可以得到: posts/index.tmpl 。
(六)加点东西,使得事情朝着有意思的方向进行! 我们为了使得网页画面更有趣,这里使用了多个文件,分别是index.css、index.js。编写:index.css:
1 2 3 body  {background-color : #00a7d0 ;
没错只有一句话。接下来编写 index.js:
没错,也只有一句话。然后,我们把 css、js 文件引入到 index.tmpl中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 {{define "users/index.tmpl" }}"en" >"UTF-8" >"viewport"  content="width=device-width, initial-scale=1.0" >"X-UA-Compatible"  content="ie=edge" >"stylesheet"  href="/xxx/index.css" >"/xxx/index.js" ></script>
接下来写main.go:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package  mainimport  ("github.com/gin-gonic/gin" "html/template" "net/http" func  main () "/xxx" , "/Users/luliang/GoLand/gin_practice/chap5/statics" )"/Users/luliang/GoLand/gin_practice/chap5/templates/**/*" )"/posts/index" , func (c *gin.Context) "posts/index.tmpl" , gin.H{"title" : "posts/index.tmpl" ,"/users/index" , func (c *gin.Context) "users/index.tmpl" , gin.H{"title" : "送你到百度!" ,":9091" )
因为我们要把 css、js 文件加载进去,因此要用 r.Static()函数把放置静态文件的目录加入进去。为了复用 ,第一个参数“/xxx”的意思是,只要index.tmpl文件中存在“/xxx”字段就直接指到我们设置的目录。
可以看到这里出现了一个超链接,那是因为我们在这个字符后面插入了一个函数:
1 2 3 4 5 6 "safe" : func (str string ) return  template.HTML(str)
配合 index.tmpl,就可以了。
三、利用已有模板进行部署 通过以上的例子,终于学会了在模板中插入大量的css、js 进行渲染了!站长之家 ,下载一个模板:
static 外面的 index.html有用,其它都可以忽略。把 static 里面的文件夹复制到我们的工作目录:index.html文件复制到 posts(无所谓,强迫症而已),就可以使用了。
1 2 3 r.GET("/home" , func (c *gin.Context) "index.html" , nil )
这样,在地址栏输入:http://127.0.0.1:9091/home,就可以看到效果了:main.go:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 package  mainimport  ("github.com/gin-gonic/gin" "html/template" "net/http" func  main () "/xxx" , "/Users/luliang/GoLand/gin_practice/chap5/statics" )"safe" : func (str string ) return  template.HTML(str)"/Users/luliang/GoLand/gin_practice/chap5/templates/**/*" )"/posts/index" , func (c *gin.Context) "posts/index.tmpl" , gin.H{"title" : "posts/index.tmpl" ,"/users/index" , func (c *gin.Context) "users/index.tmpl" , gin.H{"title" : "<a href='https://www.baidu.com'>送你到百度!</a>" ,"/home" , func (c *gin.Context) "index.html" , nil )":9091" )
这意味着,我们以后要想写网页,根本不需要进行大量的无意义的编程,利用 ChatGPT,我们可以写出大量的优秀的css、js 网页,我们要做的只是进行适量的改动,这将极大地丰富我们的创造力!
四、总结 本文从简单到难,对Go Web中 gin 框架下的模板渲染进行了简单的阐述。
全文完,感谢阅读!