I’m working on a project with a Golang backend and a REACT frontend. Built the backend using Gin and was able to create a basic API. I wanted to not only test out the api but also figure out additional API calls I would need for the frontend. I’m primarily backend engineer and who can write frontend code when I had to. I didn’t feel like creating an entire REACT app and going through the process of figuring out the deployment so I decided to be lazy and serve html via Gin.
Using HTML Templates in Go
Writing HTML template in Go is not that difficult. Its basically a static html file with an action pipeline. A few examples of action pipelines:
{{/* a comment */}}
{{.}}
{{.Title}}
{{if .Done}} {{else}} {{end}}
{{range .Todos}} {{.}} {{end}}
{{block "content" .}} {{end}}
Defines a comment
Renders the root element
Renders the “Title”-field in a nested element
Defines an if-Statement
Loops over all “Todos” and renders each using {{.}}
Defines a block with the name “content”
Here is an example template :
<html>
<header>
<title>My Template</title>
</header>
<body>
{{range .Players}}
<div id="playerList">
{{.Rank}} - {{.Name}}
</div>
{{end}
</body>
</html>
Serving the Pages Via Gin
Now that I have a template how do I serve it via Gin. First create a directory named templates and save the above example as index.tmpl .Data for the template must be passed using a Go struct. The files must be loaded using LoadHTMLGlob() or LoadHTMLFiles().
Here is an example of how to serve html file using Gin:
func main() {
router := gin.Default()
router.LoadHTMLGlob("templates/*")
data := []struct {
Rank string
Name string
}{
{"1", "Michael Jordan"},
{"2", "Larry Bird"},
}
router.GET("/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", gin.H{
"Players": data,
})
})
router.Run(":8080")
}
This code will read templates from the templates directory, create an array with the required data and display the template using the provided data. Gin will detect if a change has been made to templates and automatically reload it. Templates can use CSS and Javascript if you can to get more fancy.
This is a simple workaround to avoid having to create a full blown REACT app and shouldn’t be seen as a long term solution.