lenslocked/views/template.go

83 lines
1.8 KiB
Go

package views
import (
"bytes"
"fmt"
"html/template"
"io"
"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")
var buf bytes.Buffer
err = tpl.Execute(&buf, data)
if err != nil {
log.Printf("Error executing template: %v", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
io.Copy(w, &buf)
}
func (t Template) TestTemplate(data interface{}) error {
var testWriter strings.Builder
tpl, err := t.htmlTpl.Clone()
if err != nil {
return err
}
tpl = tpl.Funcs(template.FuncMap{
"csrfField": func() template.HTML {
return `<div class="hidden">STUB: PLACEHOLDER</div>`
},
})
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, error) {
return `<div class="hidden">STUB: PLACEHOLDER</div>`, fmt.Errorf("csrfField Not Implimented")
},
})
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
}