package partials import ( "bytes" "fmt" "html/template" "io/fs" "path/filepath" "strings" ) type Namespace struct { dir fs.FS funcMap template.FuncMap } func New(dir fs.FS, funcMap template.FuncMap) *Namespace { return &Namespace{ dir: dir, funcMap: funcMap, } } func (ns *Namespace) Include(name string, data any) (template.HTML, error) { name = strings.TrimPrefix(filepath.Clean(name), "partials/") if filepath.Ext(name) == "" { name += ".html" } tpl, err := template.New(name).Funcs(ns.funcMap).ParseFS(ns.dir, name) if err != nil { return "", fmt.Errorf("cannot parse partial: %w", err) } buf := bytes.NewBuffer(nil) if err = tpl.Execute(buf, data); err != nil { return "", fmt.Errorf("cannot execute partial: %w", err) } return template.HTML(buf.String()), nil }