package views import ( "fmt" "html/template" "io/fs" "log" "net/http" "os" "strings" "github.com/gorilla/csrf" ) type Template struct { htmlTpl *template.Template } func (t Template) Execute(w http.ResponseWriter, r *http.Request, data interface{}) { tpl, err := t.htmlTpl.Clone() if err != nil { log.Printf("Template Clone Error: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } tpl = tpl.Funcs(template.FuncMap{ "csrfField": func() template.HTML { return csrf.TemplateField(r) }, }) w.Header().Set("Content-Type", "text/html; charset=utf8") err = tpl.Execute(w, data) if err != nil { log.Printf("Error executing template: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } } func (t Template) TestTemplate(data interface{}) error { var testWriter strings.Builder tpl, err := t.htmlTpl.Clone() if err != nil { return err } return tpl.Execute(&testWriter, data) } func FromFile(pattern ...string) (Template, error) { fs := os.DirFS(".") return FromFS(fs, pattern...) } func FromFS(fs fs.FS, pattern ...string) (Template, error) { tpl := template.New(pattern[0]) tpl = tpl.Funcs(template.FuncMap{ "csrfField": func() template.HTML { return `` }, }) tpl, err := tpl.ParseFS(fs, pattern...) if err != nil { return Template{}, fmt.Errorf("Error parsing template: %v", err) } return Template{ htmlTpl: tpl, }, nil } func Must(t Template, err error) Template { if err != nil { panic(err) } return t }