Implement shared template layout system

This commit is contained in:
bronku 2025-03-29 07:33:23 +01:00
parent 3be7fb76e7
commit 08b669fd8f
9 changed files with 69 additions and 45 deletions

View file

@ -8,7 +8,7 @@ import (
)
type Server struct {
tmpl *template.Template
tmpl map[string]*template.Template
s *store.Store
http.Handler
}
@ -19,13 +19,13 @@ func (h *Server) Close() {
func (h *Server) loadHandler() {
mux := http.NewServeMux()
mux.HandleFunc("GET /order/", h.render(h.order, "order.html"))
mux.HandleFunc("GET /order/", h.render(h.order, "order"))
mux.HandleFunc("GET /", h.redirect("/orders", http.StatusSeeOther))
mux.HandleFunc("GET /orders", h.render(h.orders, "orders.html"))
mux.HandleFunc("POST /order/", h.render(h.postOrder, "confirmation.html"))
mux.HandleFunc("GET /cakes", h.render(h.cakes, "cakes.html"))
mux.HandleFunc("GET /cake/", h.render(h.cake, "cake.html"))
mux.HandleFunc("POST /cake/", h.render(h.postCake, "confirmation.html"))
mux.HandleFunc("GET /orders", h.render(h.orders, "orders"))
mux.HandleFunc("POST /order/", h.render(h.postOrder, "confirmation"))
mux.HandleFunc("GET /cakes", h.render(h.cakes, "cakes"))
mux.HandleFunc("GET /cake/", h.render(h.cake, "cake"))
mux.HandleFunc("POST /cake/", h.render(h.postCake, "confirmation"))
h.Handler = mux
}

View file

@ -13,24 +13,32 @@ import (
var templates embed.FS
func (h *Server) loadTemplates() {
var err error
h.tmpl, err = template.ParseFS(templates, "templates/*")
if err != nil {
log.Fatal(err)
h.tmpl = make(map[string]*template.Template)
pages := []string{"orders", "order", "cake", "cakes", "confirmation"}
for _, page := range pages {
tmpl, err := template.ParseFS(templates,
"templates/layout/*.html",
"templates/"+page+".html",
)
if err != nil {
log.Fatal(err)
}
h.tmpl[page] = tmpl
}
}
func (s *Server) render(fetch fetcher, templateName string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("content-type", "text/html")
data, code, err := fetch(r)
if err != nil {
logging.ErrorPage(err, code).ServeHTTP(w, r)
return
}
err = s.tmpl.ExecuteTemplate(w, templateName, data)
err = s.tmpl[templateName].ExecuteTemplate(w, "layout", data)
if err != nil {
logging.ErrorPage(err, http.StatusInternalServerError).ServeHTTP(w, r)
return
}
w.Header().Set("content-type", "text/html")
}
}

View file

@ -1,9 +1,7 @@
<header>
<h1>New Cake</h1>
</header>
<nav>
<a href="/cakes">back</a>
</nav>
{{define "title"}}
Cake
{{end}}
{{define "main"}}
<main>
<form method="post">
<div>
@ -29,3 +27,4 @@
<button type="submit">submit</button>
</form>
</main>
{{end}}

View file

@ -1,10 +1,7 @@
<header>
<h1>Kill me please</h1>
</header>
<nav>
<a href="/">orders</a>
<a href="cake">new</a>
</nav>
{{define "title"}}
Cakes
{{end}}
{{define "main"}}
<main>
<table>
<tr>
@ -25,3 +22,4 @@
{{end}}
</table>
</main>
{{end}}

View file

@ -1,9 +1,8 @@
<header>
<h1>Confirmation</h1>
</header>
<nav>
<a href="/">index</a>
</nav>
{{define "title"}}
Confirmed
{{end}}
{{define "main"}}
<main>
<h2>{{.ID}} confirmed</h2>
</main>
{{end}}

View file

@ -0,0 +1,16 @@
{{define "layout"}}
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>{{template "title" .}}</title>
</head>
<body>
<header>
<h1>{{template "title" .}}</h1>
</header>
<nav>{{template "nav" .}}</nav>
{{template "main" .}}
</body>
</html>
{{end}}

View file

@ -0,0 +1,6 @@
{{define "nav"}}
<a href="/orders">All orders</a>
<a href="/order">New order</a>
<a href="/cakes">All Cakes</a>
<a href="/cake">New Cake</a>
{{end}}

View file

@ -1,9 +1,7 @@
<header>
<h1>New Order</h1>
</header>
<nav>
<a href="/">back</a>
</nav>
{{define "title"}}
Order
{{end}}
{{define "main"}}
<main>
<form method="post">
{{with .Order}}
@ -89,3 +87,4 @@
addCake({{.ID}}, '{{.Name}} {{.Price}}', {{.Amount}})
{{end}}
</script>
{{end}}

View file

@ -1,10 +1,8 @@
<header>
<h1>Kill me please</h1>
</header>
<nav>
<a href="order">New</a>
<a href="cakes">Manage Cakes</a>
</nav>
{{define "title"}}
Orders
{{end}}
{{define "main"}}
<main>
<table>
<tr>
@ -33,3 +31,4 @@
{{end}}
</table>
</main>
{{end}}