Gin is a lightweight web framework that is widely used in Go language web development. In Gin, web applications usually only need to render a template to complete the page display. This design allows developers to focus more on the implementation of business logic and simplifies the development process. In the opinion of PHP editor Xiaoxin, this feature of Gin not only improves development efficiency, but also reduces resource usage, making Web applications more efficient. At the same time, Gin also provides a wealth of middleware and plug-ins, providing developers with more scalability and flexibility. In short, Gin's simplicity and powerful features make it the preferred framework for many developers.
I have a Gin web application that contains multiple HTML templates based on a set of sections and a base template. The base template seems to render fine with the relevant parts, but my main view, login, index and registration are not rendering as expected. Whenever I access the HTTP endpoint of any of these, only the register view is rendered.
Is there something missing or misconfigured in the following files that prevents my route from rendering the requested page?
My project has the following structure.
├── app ... │ ├── handlers │ │ ├── general │ │ │ └── general.go │ │ └── routes.go │ ├── main.go │ ├── reloadDev.sh │ ├── static │ │ ├── css │ │ ├── img │ │ └── js │ └── templates │ ├── home │ │ ├── index.tmpl.html │ │ ├── login.tmpl.html │ │ └── register.tmpl.html │ ├── layouts │ │ └── base.tmpl.html │ └── partials │ ├── footer.tmpl.html │ ├── head.tmpl.html │ └── navbar.tmpl.html
base.tmpl.html
{{ define "base" }} <!DOCTYPE html> <html lang="eng" data-bs-theme="dark"> {{ template "head" . }} {{template "navbar" .}} <body> {{ block "content" . }}{{ end }} </body> {{template "footer" .}} </html> {{end}}
Register.tmpl.html
{{ template "base" . }} {{ define "content" }} <div class="container"> <div class="row"> <div class="col-md-6 offset-md-3"> <h1>Register</h1> <form action="/register" method="post"> <div class="mb-3"> <label for="username" class="form-label">Username</label> <input type="text" name="username" id="username" class="form-control" placeholder="Username" required> </div> <div class="mb-3"> <label for="password" class="form-label">Password</label> <input type="password" name="password" id="password" class="form-control" placeholder="Password" required> </div> ...SNIP... <button type="submit" class="btn btn-primary">Register</button> </form> </div> </div> </div> {{ end }}
index.tmpl.html (The structure of the login is the same as these two.)
{{ template "base" . }} {{ define "title" }}Home{{ end }} {{ define "content" }} <div class="container"> <div class="row"> <div class="col-md-6 offset-md-3"> <p>Welcome to Astra Porta.</p> <p>Click <a href="//m.sbmmt.com/link/1b8e84dcae97ad25234484e38615c570">here</a> to login.</p> </div> </div> </div> {{ end }}
HTML templates are bundled with binaries using embed.FS
.
//go:embed templates/partials/* templates/layouts/* templates/home/* var files embed.FS func main() { router := setupRouter() err := router.Run() if err != nil { panic(err) } } func setupRouter() *gin.Engine { router := gin.Default() subFS, e := fs.Sub(files, "templates") if e != nil { panic(e) } tmpl := template.Must(template.ParseFS( subFS, "layouts/*.html", "partials/*.html", "home/*.html", )) router.SetHTMLTemplate(tmpl) router.StaticFS("/static", http.Dir("static")) err := router.SetTrustedProxies(nil) if err != nil { panic(err) } handlers.InitializeRoutes(&router.RouterGroup) return router }
The page is rendered in my application route. References here map to the file names of *.tmpl.html
files.
func SiteIndex(c *gin.Context) { c.HTML(http.StatusOK, "index.tmpl.html", nil) } func GetRegister(c *gin.Context) { c.HTML(http.StatusOK, "register.tmpl.html", nil) } func GetLogin(c *gin.Context) { c.HTML(http.StatusOK, "login.tmpl.html", nil) }
For anyone else who encounters this problem. The solution pointed out by mkopriva in the comments is correct. I removed the base.tmpl.html
and composed each view with the updated section and target page.
title
{{ define "header" }} <!DOCTYPE html> <html lang="eng" data-bs-theme="dark"> {{template "navbar" .}} <body> {{ block "content" . }}{{ end }} <head><meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> ...SNIP... <title>App</title> </head> {{end}}
footer
{{define "footer"}} <div class="container"> <footer class="py-3 my-4" data-bs-theme="dark"> <ul class="nav justify-content-center border-bottom pb-3 mb-3"> <li class="nav-item"><a href="/" class="nav-link px-2 text-body-secondary">Home</a></li> </ul> <p class="text-center text-body-secondary">© 2024 .</p> </footer> </div> </body> </html> {{end}}
Problematic Page
{{template "header"}} <div class="container"> <div class="row"> <div class="col-md-6 offset-md-3"> <p>Welcome to Astra Porta.</p> <p>Click <a href="//m.sbmmt.com/link/1b8e84dcae97ad25234484e38615c570">here</a> to login.</p> </div> </div> </div> {{template "footer"}}
The above is the detailed content of Gin web application renders only one template. For more information, please follow other related articles on the PHP Chinese website!