// stolen from gofiber/template but simpler package render import ( "fmt" "io" "io/fs" "path/filepath" "strings" "github.com/mailgun/raymond/v2" ) var Renderer *renderer func Render(out io.Writer, name string, bind map[string]any) error { return Renderer.Render(out, name, bind) } type renderer struct { templates map[string]*raymond.Template } const ext = ".hbs" func Initialize(views fs.FS) { r := new(renderer) r.templates = make(map[string]*raymond.Template) r.registerHelpers() fs.WalkDir(views, ".", func(path string, d fs.DirEntry, err error) error { if err != nil || d.IsDir() { return err } name, hasExt := strings.CutSuffix(path, ext) if !hasExt { return nil } path = filepath.ToSlash(path) file, err := views.Open(path) if err != nil { return err } defer file.Close() buf, err := io.ReadAll(file) if err != nil { return err } tmpl, err := raymond.Parse(string(buf)) if err != nil { return err } r.templates[name] = tmpl return nil }) for j := range r.templates { for n, template := range r.templates { r.templates[j].RegisterPartialTemplate(n, template) } } Renderer = r } func (r *renderer) Render(out io.Writer, name string, bind map[string]any) error { tmpl := r.templates[name] if tmpl == nil { return fmt.Errorf("render: template %s does not exist", name) } parsed, err := tmpl.Exec(bind) if err != nil { return fmt.Errorf("render: %w", err) } if _, err = out.Write([]byte(parsed)); err != nil { return fmt.Errorf("render: %w", err) } return err }