/*
* 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()
}