100 lines
2.5 KiB
Go
100 lines
2.5 KiB
Go
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),
|
|
filepath.Join("templates", "_port_list.html"),
|
|
filepath.Join("templates", "_power_strip.html"),
|
|
)
|
|
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)
|
|
}
|