" />

欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go Web下gin框架的模板渲染的實現(xiàn)

 更新時間:2023年10月15日 12:10:09   作者:瑜陀  
Gin框架是目前非常流行的Go語言Web框架之一,作為一個輕量級的框架,Gin提供了豐富的功能和靈活的架構,本文就來介紹下Go Web下gin框架的模板渲染的實現(xiàn),感興趣的可以了解一下

〇、前言

Gin框架是一個用于構建Web應用程序的輕量級Web框架,使用Go語言開發(fā)。它具有高性能、低內存占用和快速路由匹配的特點,旨在提供簡單、快速的方式來開發(fā)可擴展的Web應用程序。
Gin框架的設計目標是保持簡單和易于使用,同時提供足夠的靈活性和擴展性,使開發(fā)人員能夠根據項目的需求進行定制。它提供了許多有用的功能,如中間件支持、路由組、請求參數解析、模板渲染等,使開發(fā)人員能夠快速構建高效的Web應用程序。

以下是Gin框架的一些主要特性:

  • 快速的性能:Gin框架采用了高性能的路由引擎,使請求路由匹配變得非??焖?。

  • 中間件支持:Gin框架支持中間件機制,允許你在請求處理過程中添加自定義的中間件,用于處理認證、日志記錄、錯誤處理等功能。

  • 路由組:Gin框架允許將路由按照邏輯組織成路由組,使代碼結構更清晰,并且可以為不同的路由組添加不同的中間件。

  • 請求參數解析:Gin框架提供了方便的方法來解析請求中的參數,包括查詢字符串參數、表單參數、JSON參數等。

  • 模板渲染:雖然Gin框架本身不提供模板引擎,但它與多種模板引擎庫(如html/template、pongo2等)集成,使你能夠方便地進行模板渲染。

  • 錯誤處理:Gin框架提供了內置的錯誤處理機制,可以捕獲和處理應用程序中的錯誤,并返回適當的錯誤響應。

總體而言,Gin框架是一個簡單、輕量級但功能強大的Web框架,非常適合構建高性能、可擴展的Web應用程序。它在Go語言社區(qū)中得到廣泛的認可,并被許多開發(fā)人員用于構建各種類型的Web應用程序。

一、html/template

html/template是Go語言標準庫中的一個包,用于生成和渲染HTML模板。它提供了一種安全且靈活的方式來生成HTML輸出,支持模板繼承、變量替換、條件語句、循環(huán)結構等功能。

html/template包的主要目標是防止常見的Web安全漏洞,如跨站腳本攻擊(XSS)。它通過自動進行HTML轉義和編碼來確保生成的HTML是安全的,并防止惡意用戶注入惡意代碼。

使用html/template包可以將動態(tài)數據與靜態(tài)HTML模板分離,使代碼更易于維護和重用。你可以定義模板文件,然后將數據傳遞給模板進行渲染,最后生成最終的HTML輸出。

(一)初次渲染

先創(chuàng)建一個名為 hello.tmpl的文件:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>Hello</title>
</head>
<body>
<p>hello, {{.}}</p>
</body>
</html>

這里的{{.}}中的.就代表了我們要填充的東東,接著創(chuàng)建我們的main.go函數:

package main

import (
	"fmt"
	"html/template"
	"net/http"
)

func sayHello(w http.ResponseWriter, r *http.Request) {
	// 請勿刻舟求劍,用絕對地址
	t, err := template.ParseFiles("/Users/luliang/GoLand/gin_practice/chap1/hello.tmpl")
	if err != nil {
		fmt.Println("http server failed:%V", err)
		return
	}
	// 渲染模板
	err = t.Execute(w, "小王子!")
	if err != nil {
		fmt.Println("http server failed:%V", err)
		return
	}
}
func main() {
	http.HandleFunc("/hello", sayHello)
	err := http.ListenAndServe(":9000", nil)
	if err != nil {
		fmt.Println("http server failed:%V", err)
		return
	}
}

使用html/template進行HTML模板渲染的一般步驟如下:

  • 定義模板:
    首先,你需要定義HTML模板??梢栽诖a中直接定義模板字符串,也可以將模板保存在獨立的文件中。比如我們創(chuàng)建了模板:hello.tmpl;

  • 創(chuàng)建模板對象:
    使用template.New()函數創(chuàng)建一個模板對象。你可以選擇為模板對象指定一個名稱,以便在渲染過程中引用它。

  • 解析模板:
    使用模板對象的Parse()或ParseFiles()方法解析模板內容。如果模板內容保存在單獨的文件中,可以使用ParseFiles()方法解析文件內容并關聯(lián)到模板對象。

  • 渲染模板:
    創(chuàng)建一個用于存儲模板數據的數據結構,并將數據傳遞給模板對象的Execute()方法。該方法將渲染模板并將結果寫入指定的輸出位置(如os.Stdout或http.ResponseWriter)。

在瀏覽器中輸入:127.0.0.0:9000/hello就可以看到結果:hello, 小王子!

(二)傳入其它數據進行渲染

上次渲染,我們用的是這一句:err = t.Execute(w, "小王子!"),可以看到我們傳入了一個字符串而已。這次我們打算傳點稍微不同的其它數據。繼續(xù)編寫模板test.tmpl:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>Hello</title>
</head>
<body>
<p>姓名: {{.Name}}</p>
<p>年齡: {{.Age}}</p>
<p>性別: {{.Gander}}</p>
</body>
</html>

可以看到,我們的模板稍微復雜起來了!繼續(xù)編寫 main.go

package main

import (
	"fmt"
	"html/template"
	"net/http"
)

type User struct {
	Name   string
	Gander string // 首字母是否大小寫,作為是否對外暴露的標識
	Age    int
}

func sayHello(w http.ResponseWriter, r *http.Request) {
	// 定義模板
	u1 := User{
		Name:   "小王子",
		Gander: "男",
		Age:    19,
	}
	// 解析模板
	t, err := template.ParseFiles("/Users/luliang/GoLand/gin_practice/chap2/test.tmpl")
	if err != nil {
		fmt.Println("ParseFiles failed:%V", err)
		return
	}
	err = t.Execute(w, u1)
	if err != nil {
		return
	}

}
func main() {
	http.HandleFunc("/hello", sayHello)
	err := http.ListenAndServe(":9000", nil)
	if err != nil {
		fmt.Println("http server failed:%V", err)
		return
	}

}

可以看到我們在里面定義了一個結構類型 User,傳入了一個 User 對象 u1:err = t.Execute(w, u1)

type User struct {
	Name   string
	Gander string // 首字母是否大小寫,作為是否對外暴露的標識
	Age    int
}

趕緊看看運行結果,可以看到結果符合預期:

姓名: 小王子
年齡: 19
性別: 男

(三)定義函數參與渲染

定義我們的模板:f.tmpl:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>hello</title>
</head>
<body>
{{ kua . }}
</body>
</html>

可以看到,我們的模板里面有一個函數名字叫做 kua,沒錯,這就是我們要的函數。

編寫main.go:

package main
import (
	"fmt"
	"html/template"
	"net/http"
)
func f(w http.ResponseWriter, r *http.Request) {
	// 定義模板
	k := func(name string) (string, error) {
		return name + "太棒了!", nil
	}
	t := template.New("f.tmpl")
	t.Funcs(template.FuncMap{
		"kua": k,
	})
	// 解析模板
	_, err := t.ParseFiles("/Users/luliang/GoLand/gin_practice/chap3/f.tmpl")
	if err != nil {
		return
	}
	// 渲染模板
	err = t.Execute(w, "小王子")
	if err != nil {
		return
	}
}
func main() {
	http.HandleFunc("/hello", f)
	err := http.ListenAndServe(":9002", nil)
	if err != nil {
		fmt.Println("http server failed:%V", err)
		return
	}

}

可以看到,我用了一個關鍵語句將函數kua 關聯(lián)到了模板:

	t.Funcs(template.FuncMap{
		"kua": k,
	})

點擊運行,可以看到結果:小王子太棒了!

(四)c.HTML() 渲染

在Gin框架中,可以使用c.HTML()方法來進行HTML模板渲染。該方法接收HTTP狀態(tài)碼、模板名稱和渲染所需的數據作為參數。

編寫模板index.tmpl:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>posts/index</title>
</head>
<body>
{{.title}}
</body>
</html>

可以看到我們只需渲染傳入對象的 title 值,編寫 main.go:

package main

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

func main() {
	r := gin.Default()
	r.LoadHTMLFiles("/Users/luliang/GoLand/gin_practice/chap4/index.tmpl")
	r.GET("/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.tmpl", gin.H{
			"title": "你好,前端真是太有意思了!",
		})
	})
	r.Run(":9091")
}

首先,創(chuàng)建一個 gin.default()路由對象,然后給該對象載入已經寫好的模板文件,之后就可以用 GET 函數進行請求了。
先看看 GET 是什么東西:

// GET is a shortcut for router.Handle("GET", path, handlers).
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
	return group.handle(http.MethodGet, relativePath, handlers)
}

它說,GET 是router.Handle("GET", path, handlers)的一個捷徑。再看看router.Handle("GET", path, handlers)是什么東西:

func (group *RouterGroup) handle(httpMethod, relativePath string, handlers HandlersChain) IRoutes {
	absolutePath := group.calculateAbsolutePath(relativePath)
	handlers = group.combineHandlers(handlers)
	group.engine.addRoute(httpMethod, absolutePath, handlers)
	return group.returnObj()
}

// Handle registers a new request handle and middleware with the given path and method.
// The last handler should be the real handler, the other ones should be middleware that can and should be shared among different routes.
// See the example code in GitHub.
//
// For GET, POST, PUT, PATCH and DELETE requests the respective shortcut
// functions can be used.
//
// This function is intended for bulk loading and to allow the usage of less
// frequently used, non-standardized or custom methods (e.g. for internal
// communication with a proxy).

原來就是做了一下中間處理,注冊了一個新的請求句柄。它還說GET, POST, PUT, PATCH、DELETE 都有類似的捷徑。之后在 handlers中放一個匿名函數:

func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.tmpl", gin.H{
			"title": "你好,前端真是太有意思了!",
		})
	}

這個函數就是用于渲染的函數。猜測c.HTML()依然是一個 shortcut:

// HTML renders the HTTP template specified by its file name.
// It also updates the HTTP code and sets the Content-Type as "text/html".
// See http://golang.org/doc/articles/wiki/
func (c *Context) HTML(code int, name string, obj any) {
	instance := c.engine.HTMLRender.Instance(name, obj)
	c.Render(code, instance)
}

可以看到真正干活的還是 Render()。

點擊運行,結果為:你好,前端真是太有意思了!

(五)從多個模板中選擇一個進行渲染

如果要渲染多個文件,該如何操作?比如我們通過輸入不同的網站,服務器這時只需要選擇不同的模板進行渲染就好。在這里創(chuàng)建了兩個模板文件,users/index.tmpl:

{{define "users/index.tmpl"}}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>users/index</title>
    </head>
    <body>
    {{.title}}
    </body>
    </html>
{{end}}

posts/index.tmpl:

{{define "posts/index.tmpl"}}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>posts/index</title>
    </head>
    <body>
    {{.title}}
    </body>
    </html>
{{end}}

這里使用了{{define "posts/index.tmpl"}}...{{end}}結構,對模板文件進行了命名。
編寫main.go:

package main

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

func main() {
	r := gin.Default()
	
	r.LoadHTMLGlob("/Users/luliang/GoLand/gin_practice/chap5/templates/**/*")
	r.GET("/posts/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
			"title": "posts/index.tmpl",
		})
	})
	r.GET("/users/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
			"title": "送你到百度!",
		})
	})
	r.Run(":9091")
}

我們在在瀏覽器地址欄輸入http://127.0.0.1:9091/users/index可以得到:送你到百度!;而輸入http://127.0.0.1:9091/posts/index可以得到:posts/index.tmpl。

(六)加點東西,使得事情朝著有意思的方向進行!

我們?yōu)榱耸沟镁W頁畫面更有趣,這里使用了多個文件,分別是index.css、index.js。編寫:index.css:

body {
    background-color: #00a7d0;
}

沒錯只有一句話。接下來編寫 index.js:

alert("Hello, Web!")

沒錯,也只有一句話。然后,我們把 css、js 文件引入到 index.tmpl中:

{{define "users/index.tmpl"}}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <link rel="stylesheet" href="/xxx/index.css" rel="external nofollow" >
        <title>users/index</title>
    </head>
    <body>
    {{.title}}

    <script src="/xxx/index.js"></script>
    </body>
    </html>
{{end}}

接下來寫main.go:

package main

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

func main() {
	r := gin.Default()
	// 加載靜態(tài)文件
	r.Static("/xxx", "/Users/luliang/GoLand/gin_practice/chap5/statics")
	
	r.LoadHTMLGlob("/Users/luliang/GoLand/gin_practice/chap5/templates/**/*")
	r.GET("/posts/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
			"title": "posts/index.tmpl",
		})
	})
	r.GET("/users/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
			"title": "送你到百度!",
		})
	})

	r.Run(":9091")
}

因為我們要把 css、js 文件加載進去,因此要用 r.Static()函數把放置靜態(tài)文件的目錄加入進去。為了復用,第一個參數“/xxx”的意思是,只要index.tmpl文件中存在“/xxx”字段就直接指到我們設置的目錄。
運行結果:首先 js 文件會首先渲染:

在這里插入圖片描述

之后,css 文件會渲染:

在這里插入圖片描述

可以看到這里出現(xiàn)了一個超鏈接,那是因為我們在這個字符后面插入了一個函數:

// 添加自定義函數
	r.SetFuncMap(template.FuncMap{
		"safe": func(str string) template.HTML {
			return template.HTML(str)
		},
	})

配合 index.tmpl,就可以了。

在這里插入圖片描述

二、利用已有模板進行部署

通過以上的例子,終于學會了在模板中插入大量的css、js 進行渲染了!
首先找到某個網站,比如站長之家,下載一個模板:

在這里插入圖片描述

選擇第一個,下載之后解壓:

在這里插入圖片描述

static 外面的 index.html有用,其它都可以忽略。把 static 里面的文件夾復制到我們的工作目錄:

同時,把 index.html文件復制到 posts(無所謂,強迫癥而已),就可以使用了。

	r.GET("/home", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.html", nil)
	})

這樣,在地址欄輸入:http://127.0.0.1:9091/home,就可以看到效果了:

在這里插入圖片描述

渲染的相當完美!這里會存在一些小細節(jié),比如在 index.html文件中需要把 css、js文件的地址進行變更,變更到你放置這些文件的地址:

在這里插入圖片描述

代碼附上main.go

package main

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

func main() {
	r := gin.Default()
	// 加載靜態(tài)文件
	r.Static("/xxx", "/Users/luliang/GoLand/gin_practice/chap5/statics")
	// 添加自定義函數
	r.SetFuncMap(template.FuncMap{
		"safe": func(str string) template.HTML {
			return template.HTML(str)
		},
	})
	r.LoadHTMLGlob("/Users/luliang/GoLand/gin_practice/chap5/templates/**/*")
	r.GET("/posts/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
			"title": "posts/index.tmpl",
		})
	})
	r.GET("/users/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
			"title": "<a ,
		})
	})
	r.GET("/home", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.html", nil)
	})

	r.Run(":9091")
}

這意味著,我們以后要想寫網頁,根本不需要進行大量的無意義的編程,利用 ChatGPT,我們可以寫出大量的優(yōu)秀的css、js 網頁,我們要做的只是進行適量的改動,這將極大地豐富我們的創(chuàng)造力!

三、總結

本文從簡單到難,對Go Web中 gin 框架下的模板渲染進行了簡單的闡述。

到此這篇關于Go Web下gin框架的模板渲染的實現(xiàn)的文章就介紹到這了,更多相關Go  gin 模板渲染內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Go映射的使用

    Go映射的使用

    Go提供了另一個重要的數據類型,稱為map,它將唯一鍵映射到值,本文主要介紹了Go映射的使用,包括聲明映射、初始化映射、操作映射等,感興趣的可以了解一下
    2023-11-11
  • golang 實現(xiàn)tcp server端和client端,并計算RTT時間操作

    golang 實現(xiàn)tcp server端和client端,并計算RTT時間操作

    這篇文章主要介紹了golang 實現(xiàn)tcp server端和client端,并計算RTT時間操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • golang小游戲開發(fā)實戰(zhàn)之飛翔的小鳥

    golang小游戲開發(fā)實戰(zhàn)之飛翔的小鳥

    這篇文章主要給大家介紹了關于golang小游戲開發(fā)實戰(zhàn)之飛翔的小鳥的相關資料,,本文可以帶你你從零開始,一步一步的開發(fā)出這款小游戲,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-03-03
  • 淺析Go語言中的Range關鍵字

    淺析Go語言中的Range關鍵字

    Range是go語言中很獨特的一個關鍵詞,也相當好用。下面就跟著小編來再聊聊這個Range關鍵字,有需要的朋友們可以參考借鑒。
    2016-09-09
  • Golang中的Unicode與字符串示例詳解

    Golang中的Unicode與字符串示例詳解

    這篇文章主要給大家介紹了關于Golang中Unicode與字符串的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Golang具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2020-05-05
  • 使用Go進行單元測試的實現(xiàn)

    使用Go進行單元測試的實現(xiàn)

    這篇文章主要介紹了使用Go進行單元測試的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-11-11
  • golang定時器Timer的用法和實現(xiàn)原理解析

    golang定時器Timer的用法和實現(xiàn)原理解析

    這篇文章主要介紹了golang定時器Ticker,本文主要來看一下Timer的用法和實現(xiàn)原理,需要的朋友可以參考以下內容
    2023-04-04
  • Golang Mongodb模糊查詢的使用示例

    Golang Mongodb模糊查詢的使用示例

    這篇文章主要給大家介紹了關于Golang Mongodb模糊查詢的使用示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-02-02
  • Go語言實現(xiàn)lru淘汰策略和超時過期

    Go語言實現(xiàn)lru淘汰策略和超時過期

    緩存的大小是有限的,當添加數據發(fā)現(xiàn)剩余緩存不夠時,需要淘汰緩存中的部分數據,本文主要介紹了Go語言實現(xiàn)lru淘汰策略和超時過期,感興趣的可以了解一下
    2024-02-02
  • GoFrame框架數據校驗之校驗對象校驗結構體

    GoFrame框架數據校驗之校驗對象校驗結構體

    這篇文章主要為大家介紹了GoFrame框架數據校驗之校驗對象校驗結構體示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06

最新評論