日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

golang微服务框架中如何扩展go-zero使之支持html模板解析自动化

發布時間:2023/12/15 综合教程 25 生活家
生活随笔 收集整理的這篇文章主要介紹了 golang微服务框架中如何扩展go-zero使之支持html模板解析自动化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本篇文章為大家展示了golang微服務框架中如何擴展go-zero使之支持html模板解析自動化,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

go-zero本身支持html模板解析,我們只需要添加url對應模板解hanlder,實現邏輯就可以了

但是winlion太懶了,我甚至想

  • 不寫任何一個和模板相關的handler

  • 如果有新的模板,直接把模板到某個特定目錄就好,不要動任何go代碼

  • 在開發環境下沒有緩存,修改了模板文件無需重啟

需求在這里,開擼吧

在代碼開始前,你可能需要閱讀

金光燦燦的Gorm V2+適合創業的golang微服務框架go-zero實戰 如果對go-zero已經了解,直接跳過吧

創建項目

生成go.mod文件

以如下指令創建項目

mkdirhtml
cdhtml
gomodinithtml

定義html.api

本文設計API如下 |描述|格式|方法|參數|返回|是否需要鑒權| |----|----|----|----|----|----| |用戶登錄|/open/authorization|post|mobile:手機號,passwd:密碼,code:圖片驗證碼|id:用戶ID,token:用戶token|否|

根據以上描述,書寫api的模板文件如下

type(
	UserOptReqstruct{
		mobilestring`form:"mobile"`
		passwdstring`form:"passwd"`
		codestring`form:"code,optional"`
	}

	UserOptRespstruct{
		iduint`json:"id"`
		tokenstring`json:"token"`
	}
)

servicehtml-api{
	@server(
		handler:authorizationHandler
		folder:open
	)
	post/open/authorization(UserOptReq)returns(UserOptResp)
	
}

注意

  • 本文和html模板相關,可以不適用goctl工具

  • 但是由于使用工具可以為我們節省很多搭建框架相關的工作,所以建議使用用ctl生成

生成代碼

采用如下指令生成代碼

goctlapigo-apihtml.api-dir.

此時用go run html.go指令可以發現系統以及運行

html模板自動解析實現思路

模板解析需要了解如下倆個已知知識點

  • html網頁輸出本質上是get請求輸出

  • 相對于一個項目來說,模板文件個數是有限的,因此我們可以將模板枚舉出來,完成訪模板名稱和請求之間的映射

對于第一個,我們可以構建get路由來實現請求,以首頁請求http://127.0.0.1:8888/index.html為例,核心代碼如下,

	htmltplrouter:=rest.Route{
			Method:http.MethodGet,
			Path:"/index.html",
			Handler:htmlhandler(...),
	}

	engine.AddRoute(htmltplrouter)

在上述代碼中,htmlhandler函數實現了對請求的響應,也就是解析了模板并將模板內容輸出

//gloabtemplate:全局解析的模板參數
//tplname:模板名稱,
//serverCtx應用配置
funchtmlhandler(gloabtemplate*template.Template,tplnamestring,serverCtx*svc.ServiceContext)http.HandlerFunc{
	returnfunc(whttp.ResponseWriter,r*http.Request){
		//模板名字就是r.URL.Path
		t:=gloabtemplate
		//如果是調試模式,則支持熱解析
		ifserverCtx.Config.Debug{
			t,_=template.New("").Funcs(FuncMap()).ParseGlob(serverCtx.Config.TemplatePattern)
		}
		err:=t.ExecuteTemplate(w,tplname,r.URL.Query())
		iferr!=nil{
			httpx.Error(w,err)
		}
	}
}

如何建立uri和模板名稱之間的映射關系

這里有幾個點需要強調:

  • 在golang中,每個包含模板內容的html文件會被解析成一個模板,如在view/www/下新建test.html文件,即使里面沒有內容,系統也會將其解析得到一個名叫test.html的模板。

  • 如果在模板文件以template標簽中定義名稱為www/test.html的模板,則系統又會解析得到一個名叫www/test.html的模板,此時存在倆個模板,一個名叫test.html,一個名叫www/test.html

view/www/test.html文件內容如下

{{define"www/test.html"}}
<h2>這是模板www/test.html的內容</h2>
{{end}}

因此我們可以取巧,將模板名稱命名成需要建立映射關系的uri 比如外部通過http://127.0.0.1:8888/www/test.html來訪問,此時req.URI.path為/www/test.html 我們可以用這個作為模板名稱

如何枚舉模板

這里用到了ParseGlob函數,這個函數本質上是對filepath.ParseGlob()template.ParseFiles()的封裝,可以遍歷滿足一定格式的路徑的所有文件,假設我們建立模板存放目錄internal\view如下

tree/F/A
|go.mod
|go.sum
|html.api
|html.go
|readme.md
|
+---etc
|html-api.yaml
|
\---internal
+---config
|config.go
|
+---handler
||routes.go
||
|\---open
|authorizationhandler.go
|
+---logic
|\---open
|authorizationlogic.go
|
+---svc
|servicecontext.go
|
+---types
|types.go
|
\---view
+---public
|footer.html
|header.html
|
\---www
index.html
test.html

則我們可以使用格式字符串 ./internal/view/**/* 來遍歷并解析并解析模板,建立模板和uri之間的對應關系,核心代碼如下

gloabtemplate,err:=template.New("").Funcs(FuncMap()).ParseGlob("./internal/view/**/*")
//range輪詢
for_,tpl:=rangegloabtemplate.Templates(){
		patern:=tpl.Name()
		if!strings.HasPrefix(patern,"/"){
			patern="/"+patern
		}

		//首頁默認index.htmlindex.htmindex.php
		tplname:=tpl.Name()
		if0==len(tplname){
			tplname=serverCtx.Config.TemplateIndex
		}

		pageRouters=append(pageRouters,rest.Route{
			Method:http.MethodGet,
			Path:patern,
			Handler:htmlhandler(gloabtemplate,tplname,serverCtx),
		})
		logx.Infof("registerpage%s%s",patern,tplname)
	}
	//添加到engin路由中
	engine.AddRoutes(pageRouters)

如何在模板中使用函數

有時候我們需要在模板中使用函數,則需要用到函數映射功能,golang提供接口函數Funcs()來注入,

假設我們需要在/www/version.html中查看系統版本,應該怎么做呢?

  1. 定義相關函數

//handlers\funcs.go
packagehandler

import(
	"html/template"
)

//定義
varfuncsMaptemplate.FuncMap=make(template.FuncMap)

funcFuncMap()template.FuncMap{

	funcsMap["version"]=version
	funcsMap["hello"]=hello

	returnfuncsMap
}
funcversion()string{
	//這個函數返回當前版本號0.0.1
	return"0.01"

}
funchello(strstring)string{
	//這個函數返回當前版本號0.0.1
	return"hello"+str

}

應用可以通過 template.New("").Funcs(FuncMap())來注入響應函數

  1. 定義模板文件 新建文件view/www/version.html,內容如下

{{define"www/version.html"}}
<h2>當前版本號:{{version}}</h2>
<h2>這里測試帶參數的函數:{{hello"word"}}</h2>
{{end}}
  1. 無參數的函數展示 此時模板文件中通過 {{version}} 即可調用并顯示版本號0.01

  2. 有參數的函數 對應有參數的函數,按照參數順序排列,中間用空格隔開

  3. 以上顯示結果

當前版本號:0.01
這里測試帶參數的函數:helloword

如何模板嵌套

使用templete指令進行嵌套

新建view/public/header.html內容如下

<!--頂部菜單Start-->
<divclass="top-menu-wrapperindex-menu">
<h2>這是Head</h2>
</div>

新建view/public/footer.html內容如下

<!--頂部菜單Start-->
<divclass="top-menu-wrapperindex-menu">
<h2>這是footer</h2>
</div>

新建view/www/index.html文件,內容如下

<!DOCTYPEhtml>
<html>
<head></head>
<body>
{{template"header.html".}}
<divclass="content-box"data-spy="scroll"data-target=".section-scrollspy">
<h2>這是Index的內容</h2>
</div>
{{template"footer.html".}}
</body>
</html>

此時編譯后即可得到如下內容

這是Head 這是Index的內容 這是footer

如何在模板中使用變量

  • 在模板中直接使用 首先需要將變量暴露到模板中,這里我們使用到了ExecuteTemplate函數,該函數第三個參數即可以在模板里面訪問的參數,比如如下代碼,則在模板中可以訪問Query了

	data:=r.URI.Query
	err:=t.ExecuteTemplate(w,tplname,data)

新建view/www/arg.html文件

{{define"www/arg.html"}}
<h6>arga={{.arga}}</h6>
<h6>argb={{.argb}}</h6>
{{end}}

請求訪問方式http://127.0.0.1:8888/www/arg.html?arga=123&argb=456

系統返回結果

arga=[123]
argb=[456]
  • 在嵌套模板中使用

在嵌套模板中使用需要將對象傳入,方式是在模板名后加一個.,如下 新建view/www/embd.html文件

{{define"www/embd.html"}}
沒加點:{{template"www/arg.html"}}
=======
加點:{{template"www/arg.html".}}
{{end}}

結果如下

沒加點:
<h6>arga=</h6>
<h6>argb=</h6>
=======
加點:
<h6>arga=[123]</h6>
<h6>argb=[456]</h6>

如何實現模板熱更新

假設我們的應用支持開發模式和生產模式,在生產模式下,由于有性能考慮,系統不需要每次訪問都解析模板。而在開發模式下,每個模板有所任何小的修改,我們都希望模板能自動更新,怎么實現這個功能呢? 方案很多,有文件監聽方案,如github.com/fsnotify/fsnotify監聽模板目錄,也有標記位方案,無論模板有沒有變動,只要是開發模式,每次請求都重新加載模板并解析,gin就是這種方案,本文也采用這種方案,核心代碼如下

//模板名字就是r.URL.Path
		t:=gloabtemplate
		//如果是debug模式
		ifserverCtx.Config.Debug{
			//每次都重新解析
			t,_=template.New("").Funcs(FuncMap()).ParseGlob(serverCtx.Config.TemplatePattern)
		}
		err:=t.ExecuteTemplate(w,tplname,r.URL.Query())

如何設置首頁

本質上是指定/請求對應的模板,以及系統錯誤對應的模板

for_,tpl:=rangegloabtemplate.Templates(){
		patern:=tpl.Name()
		if!strings.HasPrefix(patern,"/"){
			patern="/"+patern
		}

		//處理首頁邏輯
		tplname:=tpl.Name()
		if0==len(tplname){
			//模板名稱為""那么就默認首頁吧
			//恰好/對應的模板名稱為"",
			tplname=serverCtx.Config.TemplateIndex
		}

		pageRouters=append(pageRouters,rest.Route{
			Method:http.MethodGet,
			Path:patern,
			Handler:htmlhandler(gloabtemplate,tplname,serverCtx),
		})
		logx.Infof("registerpage%s%s",patern,tplname)
	}

404等頁面

目前可以實現業務邏輯層面的404定制,如httpx.Error方法可用404.html替代。 對于部分場景如訪問一個不存在的url,則需要go-zero官方提供支持,并開發接口。

集成

以上操作完成后,我們得到如下項目目錄,

tree/F/A

|go.mod
|go.sum
|html.api
|html.go
|readme.md
|
+---etc
|html-api.yaml
|
\---internal
+---config
|config.go
|
+---handler
||funcs.go
||html.go
||routes.go
||
|\---open
|authorizationhandler.go
|
+---logic
|\---open
|authorizationlogic.go
|
+---svc
|servicecontext.go
|
+---types
|types.go
|
\---view
+---public
|404.html
|footer.html
|header.html
|
\---www
arg.html
embd.html
func.html
index.html
test.html

routes.go中添加如下代碼段即可

funcRegisterHandlers(engine*rest.Server,serverCtx*svc.ServiceContext){
	engine.AddRoutes([]rest.Route{
		{
			Method:http.MethodPost,
			Path:"/open/authorization",
			Handler:open.AuthorizationHandler(serverCtx),
		},
	})
	//添加這個代碼段
	RegisterHtmlHandlers(engine,serverCtx)
}

本文代碼獲取

關注公眾號betaidea 輸入html即可獲得html解析相關代碼 關注公眾號betaidea 輸入jwt即可獲得gozero集成jwt-token相關代碼 關注公眾號betaidea 輸入gozero即可gozero入門代碼

下一篇預告

目前貌似還沒找到go-zero對static file支持的例子,類似gin哪樣做靜態資源服務貌的例子,那么明天就寫一個吧。 在go-zero的路由框架下尋找解決方案。 《用go-zero 支持文件服務》

廣而告之

送福利了uniapp用戶福音來啦! 歷經數十萬用戶考驗,我們的客服系統終于對外提供服務了。 你還在為商城接入客服煩惱嗎?只需一行代碼,即可接入啦!! 只需一行代碼!!!!

/*kefu.vue*/
<template>
	<view>
		<IdeaKefu:siteid="siteId"></IdeaKefu>
	</view>
</template>

<script>
	importIdeaKefufrom"@/components/idea-kefu/idea-kefu.vue"
exportdefault{
		components:{
			IdeaKefu
		},
		data(){
			return{
				siteId:2
			}
		}
}

效果杠杠的

總結

以上是生活随笔為你收集整理的golang微服务框架中如何扩展go-zero使之支持html模板解析自动化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。