Refactor: Centralize template loading and improve error handling

- Introduced helpers.LoadTemplateFiles() for consistent layout + topbar rendering
- Replaced repeated template.ParseFiles() calls across handlers
- Created generic RenderError(w, r, statusCode) helper
- Replaced old Render403 with flexible RenderError
- Updated AdminOnly middleware to render 403 errors with context
- Added 500.html template for graceful panic fallback
- Prepared structure for future error codes (404, 429, etc.)
This commit is contained in:
2025-04-02 09:12:13 +01:00
parent f5653f737d
commit 2498b33a9c
16 changed files with 69 additions and 106 deletions

View File

@@ -2,18 +2,23 @@ package helpers
// ToDo should be a handler?
import (
"html/template"
"fmt"
"log"
"net/http"
"synlotto-website/models"
)
func Render403(w http.ResponseWriter, r *http.Request) {
func RenderError(w http.ResponseWriter, r *http.Request, statusCode int) {
context := TemplateContext(w, r, models.TemplateData{})
tmpl := template.Must(template.New("").Funcs(TemplateFuncs()).ParseFiles(
"templates/layout.html",
"templates/error/403.html",
))
tmpl.ExecuteTemplate(w, "layout", context)
page := fmt.Sprintf("templates/error/%d.html", statusCode)
tmpl := LoadTemplateFiles(fmt.Sprintf("%d.html", statusCode), page)
w.WriteHeader(statusCode)
err := tmpl.ExecuteTemplate(w, "layout", context)
if err != nil {
log.Printf("❌ Failed to render error page for %d: %v", statusCode, err)
http.Error(w, http.StatusText(statusCode), statusCode)
}
}

View File

@@ -32,7 +32,6 @@ func TemplateContext(w http.ResponseWriter, r *http.Request, data models.Templat
}
}
// TemplateFuncs provides helper functions to be used in templates.
func TemplateFuncs() template.FuncMap {
return template.FuncMap{
"plus1": func(i int) int { return i + 1 },
@@ -63,7 +62,16 @@ func TemplateFuncs() template.FuncMap {
}
}
// SetFlash sets a flash message in session.
func LoadTemplateFiles(name string, files ...string) *template.Template {
shared := []string{
"templates/layout.html",
"templates/topbar.html",
}
all := append(shared, files...)
return template.Must(template.New(name).Funcs(TemplateFuncs()).ParseFiles(all...))
}
func SetFlash(w http.ResponseWriter, r *http.Request, message string) {
session, _ := GetSession(w, r)
session.Values["flash"] = message