package handlers import ( "fmt" "html/template" "net/http" "path/filepath" "lostcavewireplanner/internal/db" ) type Handlers struct { Store *db.Store tmpl map[string]*template.Template } func New(store *db.Store) *Handlers { funcMap := template.FuncMap{ "dict": func(values ...interface{}) (map[string]interface{}, error) { if len(values)%2 != 0 { return nil, fmt.Errorf("dict requires even arguments") } d := make(map[string]interface{}, len(values)/2) for i := 0; i < len(values); i += 2 { key, ok := values[i].(string) if !ok { return nil, fmt.Errorf("dict keys must be strings") } d[key] = values[i+1] } return d, nil }, "add": func(a, b int) int { return a + b }, "sub": func(a, b int) int { return a - b }, "safe": func(s string) template.HTML { return template.HTML(s) }, } pages := []string{ "overview.html", "rack.html", "device.html", "model_list.html", "model_form.html", "wall_sockets.html", } fragments := []string{ "connection_modal.html", } tmpl := make(map[string]*template.Template) baseFiles := []string{filepath.Join("templates", "base.html")} for _, page := range pages { files := append(baseFiles, filepath.Join("templates", page)) t, err := template.New("base.html").Funcs(funcMap).ParseFiles(files...) if err != nil { panic(fmt.Errorf("parse %s: %w", page, err)) } tmpl[page] = t } for _, frag := range fragments { t, err := template.New(frag).Funcs(funcMap).ParseFiles(filepath.Join("templates", frag)) if err != nil { panic(fmt.Errorf("parse fragment %s: %w", frag, err)) } tmpl[frag] = t } return &Handlers{Store: store, tmpl: tmpl} } func (h *Handlers) render(w http.ResponseWriter, name string, data interface{}) { t, ok := h.tmpl[name] if !ok { http.Error(w, "template not found: "+name, http.StatusInternalServerError) return } execName := name if _, isPage := map[string]bool{ "overview.html": true, "rack.html": true, "device.html": true, "model_list.html": true, "model_form.html": true, "wall_sockets.html": true, }[name]; isPage { execName = "base.html" } if err := t.ExecuteTemplate(w, execName, data); err != nil { http.Error(w, "Template error: "+err.Error(), http.StatusInternalServerError) } } func (h *Handlers) redirect(w http.ResponseWriter, r *http.Request, url string) { w.Header().Set("HX-Redirect", url) http.Redirect(w, r, url, http.StatusSeeOther) }