package handlers import ( "html/template" "log" "path/filepath" "sync" ) var ( templatesOnce sync.Once templates map[string]*template.Template ) // getTemplate returns a cached template by filename (e.g. "dashboard.html"). // Templates are parsed once from the templates/ directory on first call. func getTemplate(name string) *template.Template { templatesOnce.Do(loadTemplates) t := templates[name] if t == nil { log.Panicf("template %q not found in cache — did you delete templates/%s?", name, name) } return t } // loadTemplates walks the templates/ directory and pre-parses all .html files. func loadTemplates() { templates = make(map[string]*template.Template) files, err := filepath.Glob("templates/*.html") if err != nil { log.Panicf("list templates: %v", err) } // Parse each file into its own named template. for _, f := range files { name := filepath.Base(f) t, err := template.ParseFiles(f) if err != nil { log.Panicf("parse template %s: %v", f, err) } templates[name] = t } // Also register the inline OTP form template. otpTmpl := template.Must(template.New("otp_form").Parse(otpFormHTML)) templates["otp_form"] = otpTmpl log.Printf("Loaded %d templates", len(templates)) } // otpFormHTML is the inline OTP form template fragment with single 6-digit field. const otpFormHTML = `
`