Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to extend go-zero in golang micro-service framework to support html template parsing automation

2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article shows you how to extend go-zero in the Golang micro service framework to support the automation of html template parsing. The content is concise and easy to understand, which will definitely brighten your eyes. I hope you can get something through the detailed introduction of this article.

Go-zero itself supports html template parsing. We only need to add the url corresponding template to solve the hanlder and implement the logic.

But Winlion was so lazy that I even thought

Do not write any handler related to the template

If you have a new template, just put the template in a specific directory and don't touch any go code.

There is no cache in the development environment, and there is no need to restart the modified template file.

The need is here. Let's do it.

Before you start the code, you may need to read

Golden Gorm V2 + suitable for starting a business micro-service framework go-zero if you already know go-zero, just skip it

Create a project to generate a go.mod file

Create the project with the following instructions

Mkdir htmlcd htmlgo mod init html defines html.api

The design API of this article is as follows | description | format | method | Parameter | return |-- | open/authorization | post | mobile: mobile phone number, passwd: password, code: picture verification code | id: user ID,token: user token | No |

According to the above description, the template file for writing api is as follows

Type (UserOptReq struct {mobile string `form: "mobile" `passwd string `form: "passwd" `code string `form: "code Optional "`} UserOptResp struct {id uint `json:" id "`token string `json:" token "`}) service html-api {@ server (handler: authorizationHandler folder: open) post / open/authorization (UserOptReq) returns (UserOptResp)}

Be careful

This article is related to html templates and may not be applicable to goctl tools

However, since using tools can save us a lot of work related to building a framework, it is recommended to use ctl generation

Generate code

Generate the code using the following instructions

Goctl api go-api html.api-dir.

At this point, you can use the go run html.go instruction to discover the system and run

The idea of automatic parsing of html template

Template parsing requires the following two known knowledge points

Html web page output is essentially get request output

Compared to a project, the number of template files is limited, so we can enumerate the templates and complete the mapping between the visiting template name and the request.

For the first, we can build a get route to implement the request. Take the home request http://127.0.0.1:8888/index.html as an example, the core code is as follows

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

In the above code, the htmlhandler function implements the response to the request, that is, parses the template and outputs the template content

/ / gloabtemplate: template parameters for global resolution / / tplname: template name, / / serverCtx application configuration func htmlhandler (gloabtemplate * template.Template, tplname string, serverCtx * svc.ServiceContext) http.HandlerFunc {return func (w http.ResponseWriter, r * http.Request) {/ / template name is r.URL.Path t: = gloabtemplate / / if it is debug mode Thermal resolution if serverCtx.Config.Debug {t, _ = template.New (") .Funcs (FuncMap ()) .ParseGlob (serverCtx.Config.TemplatePattern)} err: = t.ExecuteTemplate (w, tplname, r.URL.Query ()) if err! = nil {httpx.Error (w) Err)} how to establish the mapping relationship between uri and template name

Here are a few points to emphasize:

In golang, each html file that contains template content will be parsed into a template, such as a new test.html file under view/www/, even if there is no content in it, the system will parse it into a template called test.html.

If a template named www/test.html is defined in the template file in the template tag, the system parses another template called www/test.html, and there are two templates, one named test.html and the other named www/test.html

The content of view/www/test.html file is as follows

{{define "www/test.html"}} this is the content of template www/test.html {{end}}

So we can skillfully name the template name as the uri that needs to establish a mapping relationship, for example, the external access through http://127.0.0.1:8888/www/test.html, and the req.URI.path is / www/test.html. We can use this as the template name.

How to enumerate templates

Here we use the ParseGlob function, which essentially encapsulates filepath.ParseGlob () and template.ParseFiles () and can traverse all files that meet a certain format. Suppose we set up a template to store the directory internal\ view as follows

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 |

Then we can use the format string. / internal/view/**/* to traverse and parse the template and establish the correspondence between the template and uri. The core code is as follows

Gloabtemplate,err:=template.New ("") .functions (FuncMap ()) .ParseGlob (". / internal/view/**/*") / / range polling for _, tpl: = range gloabtemplate.Templates () {patern: = tpl.Name () if! strings.HasPrefix (patern "/") {patern = "/" + patern} / / Home default index.html index.htm index.php tplname: = tpl.Name () if 0 = = len (tplname) {tplname = serverCtx.Config.TemplateIndex} pageRouters = append (pageRouters Rest.Route {Method: http.MethodGet, Path: patern, Handler: htmlhandler (gloabtemplate, tplname, serverCtx),}) logx.Infof ("register page% s% s", patern Tplname)} / / add to engin routing how engine.AddRoutes (pageRouters) uses functions in templates

Sometimes when we need to use functions in templates, we need to use function mapping. Golang provides an interface function Funcs () to inject

Suppose we need to check the system version in / www/version.html, what should we do?

Define correlation function

/ / handlers\ funcs.gopackage handlerimport ("html/template") / / define var funcsMap template.FuncMap = make (template.FuncMap) func FuncMap () template.FuncMap {funcsMap ["version"] = version funcsMap ["hello"] = hello return funcsMap} func version () string {/ / this function returns the current version number 0.0.1 return "0.01"} func hello (str string) string { / / this function returns the current version number 0.0.1 return "hello" + str}

Applications can inject response functions through template.New ("") .Funcs (FuncMap ())

Define the template file and create a new file, view/www/version.html, as follows

{{define "www/version.html"}} current version number: {{version}} the function with parameters is tested here: {{hello "word"}} {{end}}

The function with no parameter shows that the version number 0.01can be called and displayed through {{version}} in the template file.

Functions with parameters are arranged according to the order of parameters, separated by spaces.

The above shows the results

Current version number: 0.01There tests the function with parameters: hello word how to nest templates

Nesting using templete directives

The content of the new view/public/header.html is as follows

This is Head.

The content of the new view/public/footer.html is as follows

This is footer.

Create a new view/www/index.html file with the following contents

{{template "header.html".}} this is the content of Index {{template "footer.html".}}

At this point, you can get the following content after compilation

This is Head, this is Index's content, this is footer.

How to use variables in a template

For direct use in the template, we first need to expose the variable to the template. Here we use the ExecuteTemplate function. The third parameter of this function is the parameter that can be accessed in the template. For example, the following code can access Query in the template.

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

Create a new view/www/arg.html file

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

Request access method http://127.0.0.1:8888/www/arg.html?arga=123&argb=456

The system returns the result

Arga= [123] argb= [456]

Use in nested templates

To use in a nested template, you need to pass in an object by adding a. After the template name, as follows: create a new view/www/embd.html file

{{define "www/embd.html"}} no point: {{template "www/arg.html"}} = add point: {{template "www/arg.html".}} {{end}}

The results are as follows

No point added: arga=argb= add point: arga= [123] argb= [456] how to achieve hot template update

Assuming that our application supports development mode and production mode, in production mode, due to performance considerations, the system does not need to parse the template every time it visits. In the development mode, each template has any small changes, we all hope that the template can be updated automatically, how to achieve this function? There are many solutions, such as github.com/fsnotify/fsnotify listening template directory and tag bit scheme. Regardless of whether the template has been changed or not, as long as it is in the development mode, the template will be reloaded and parsed every time. Gin is this kind of scheme. This scheme is also used in this paper. The core code is as follows

/ / template name is r.URL.Path t: = gloabtemplate / / if it is debug mode if serverCtx.Config.Debug {/ / reparse t every time _ = template.New ("") .Funcs (FuncMap ()) .ParseGlob (serverCtx.Config.TemplatePattern)} err: = t.ExecuteTemplate (w, tplname, r.URL.Query ()) how to set the home page

In essence, it is the template corresponding to the specified / request and the template corresponding to the system error.

For _, tpl: = range gloabtemplate.Templates () {patern: = tpl.Name () if! strings.HasPrefix (patern "/") {patern = "/" + patern} / / processing home page logic tplname: = tpl.Name () if 0 = = len (tplname) {/ / template name is "" so default home page / / exactly / the corresponding template name is "" Tplname = serverCtx.Config.TemplateIndex} pageRouters = append (pageRouters, rest.Route {Method: http.MethodGet, Path: patern, Handler: htmlhandler (gloabtemplate, tplname, serverCtx) }) logx.Infof ("register page% s s", patern, tplname)} 404 and other pages

At present, 404 customization at the business logic level can be implemented, for example, the httpx.Error method can be replaced by 404.html. For some scenarios, such as accessing a url that does not exist, the official support of go-zero is required and the interface is developed.

Integration

After the above operation is completed, we get the following project directory

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

Just add the following code snippet to routes.go

Func RegisterHandlers (engine * rest.Server, serverCtx * svc.ServiceContext) {engine.AddRoutes ([] rest.Route {{Method: http.MethodPost, Path: "/ open/authorization", Handler: open.AuthorizationHandler (serverCtx),} }) / / add this code snippet RegisterHtmlHandlers (engine, serverCtx)} get the code of this article

Follow the official account betaidea input html to get the html parsing related code follow the official account betaidea input jwt to get the gozero integration jwt-token related code follow the official account betaidea input gozero to get the gozero entry code

The next notice

At present, it seems that there is no example of go-zero 's support for static file, similar to gin's example of how to do static resource services, so write one tomorrow. Find a solution under the routing framework of go-zero. "supporting file services with go-zero"

Advertise it widely.

Send welfare uniapp user gospel is coming! After the test of hundreds of thousands of users, our customer service system finally provides services. Are you still worried about the mall's access to customer service? Just one line of code, you can access it! Just one line of code!

/ * kefu.vue*/ import IdeaKefu from "@ / components/idea-kefu/idea-kefu.vue" export default {components: {IdeaKefu} Data () {return {siteId:2}

The effect of leverage

The above is how to extend go-zero in the Golang micro services framework to support automation of html template parsing. Have you learned any knowledge or skills? If you want to learn more skills or enrich your knowledge reserve, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report