/* * The template engine is inspired by the one in miniflux * https://github.com/miniflux/v2/blob/1fd4c4ef132670de15f1c330607773ebfd3b042f/template/engine.go */ package template import ( "bytes" "embed" "html/template" "log" "strings" ) var TmplEngine *TemplateEngine type TemplateEngine struct { templates map[string]*template.Template } func NewTemplateEngine() error { TmplEngine = &TemplateEngine{ templates: make(map[string]*template.Template), } err := TmplEngine.LoadTemplates() if err != nil { return err } return nil } //go:embed templates/common/*.tmpl var commonReader embed.FS //go:embed templates/*tmpl var contentReader embed.FS func (te *TemplateEngine) LoadTemplates() error { var commonContent strings.Builder commonTmpls, err := commonReader.ReadDir("templates/common") if err != nil { return err } for _, tmpl := range commonTmpls { log.Printf("[tixe/template] Loading common template '%s'", tmpl.Name()) readData, err := commonReader.ReadFile("templates/common/" + tmpl.Name()) if err != nil { return err } commonContent.Write(readData) } contentTmpls, err := contentReader.ReadDir("templates") if err != nil { return err } for _, tmpl := range contentTmpls { log.Printf("[tixe/template] Loading content template '%s'", tmpl.Name()) readData, err := contentReader.ReadFile("templates/" + tmpl.Name()) if err != nil { return err } var templateContents strings.Builder templateContents.WriteString(commonContent.String()) templateContents.Write(readData) te.templates[tmpl.Name()] = template.Must(template.New("tixe").Parse(templateContents.String())) } return nil } func (te *TemplateEngine) Render(name string, data map[string]interface{}) []byte { tmpl, ok := te.templates[name] if !ok { log.Fatalf("[tixe/template] Template '%s' not found", name) } var buf bytes.Buffer err := tmpl.ExecuteTemplate(&buf, "tixe", data) if err != nil { log.Fatalf("[tixe/template] Template '%s' failed to execute", err) } return buf.Bytes() }