package web import ( "fmt" "html/template" "log/slog" "net/http" ) // PageData is the view model passed to every HTML template. type PageData struct { Active string Build BuildInfo } // Renderer parses and executes HTML templates from the embedded FS. type Renderer struct { tmpls map[string]*template.Template } var pageNames = []string{"adults", "juniors", "payments", "sync", "flush_cache"} // NewRenderer parses all templates from the embedded FS. // A parse failure should be treated as a startup-time fatal error. func NewRenderer() (*Renderer, error) { tmpls := make(map[string]*template.Template, len(pageNames)) for _, name := range pageNames { t, err := template.New("").ParseFS(templateFS, "templates/base.tmpl", "templates/partials/nav.tmpl", "templates/partials/footer.tmpl", "templates/"+name+".tmpl", ) if err != nil { return nil, fmt.Errorf("parse template %q: %w", name, err) } tmpls[name] = t } return &Renderer{tmpls: tmpls}, nil } // Render executes the named template with data, writing to w. func (r *Renderer) Render(w http.ResponseWriter, name string, data any) { t, ok := r.tmpls[name] if !ok { http.Error(w, "template not found: "+name, http.StatusInternalServerError) return } w.Header().Set("Content-Type", "text/html; charset=utf-8") if err := t.ExecuteTemplate(w, "base", data); err != nil { slog.Error("render template", "name", name, "err", err) } }