package main import ( "html/template" "io" "os" "path/filepath" "sync" ) type TemplateRenderer struct { dir string templates map[string]*template.Template mu sync.RWMutex } func NewTemplateRenderer(dir string) (*TemplateRenderer, error) { tr := &TemplateRenderer{ dir: dir, templates: make(map[string]*template.Template), } if err := tr.loadAll(); err != nil { return nil, err } return tr, nil } func (tr *TemplateRenderer) loadAll() error { entries, err := os.ReadDir(tr.dir) if err != nil { return err } for _, e := range entries { if e.IsDir() || filepath.Ext(e.Name()) != ".html" { continue } path := filepath.Join(tr.dir, e.Name()) tmpl, err := template.ParseFiles(path) if err != nil { return err } tr.templates[e.Name()] = tmpl } return nil } func (tr *TemplateRenderer) Render(w io.Writer, name string, data any) error { tr.mu.RLock() tmpl, ok := tr.templates[name] tr.mu.RUnlock() if !ok { return os.ErrNotExist } return tmpl.Execute(w, data) }