summaryrefslogtreecommitdiff
path: root/internal/templatemanager/templatemanager.go
diff refs
from: back
to: back
| flip
diff options
context:
space:
mode:
Diffstat (limited to 'internal/templatemanager/templatemanager.go')
-rw-r--r--internal/templatemanager/templatemanager.go120
1 files changed, 120 insertions, 0 deletions
diff --git a/internal/templatemanager/templatemanager.go b/internal/templatemanager/templatemanager.go
new file mode 100644
index 0000000..75309e4
--- /dev/null
+++ b/internal/templatemanager/templatemanager.go
@@ -0,0 +1,120 @@
+package templatemanager
+
+import (
+ "bytes"
+ "fmt"
+ "html/template"
+ "path/filepath"
+ "strings"
+)
+
+type TemplateManager struct {
+ templates map[string]templateManagerRender
+}
+
+type templateManagerRender struct {
+ Main string
+ Tmpl *template.Template
+}
+
+type TemplateManagerTemplates struct {
+ Name string
+ Files []string
+}
+
+var templateFuncMap = template.FuncMap{
+ "contains": strings.Contains,
+ "iterate": func(count uint) []uint {
+ items := make([]uint, count)
+ for i := range count {
+ items[i] = i
+ }
+ return items
+ },
+ "replace": strings.ReplaceAll,
+}
+
+func NewTemplateManager(templates ...TemplateManagerTemplates) (*TemplateManager, error) {
+ templateMap := make(map[string]templateManagerRender)
+
+ for _, tmplStruct := range templates {
+ tmpl := template.New(tmplStruct.Name).Funcs(templateFuncMap)
+ if len(tmplStruct.Files) == 0 {
+ templateMap[tmplStruct.Name] = templateManagerRender{
+ Main: "",
+ Tmpl: tmpl,
+ }
+ continue
+ }
+ tmpl, err := tmpl.ParseFiles(tmplStruct.Files...)
+ if err != nil {
+ return nil, err
+ }
+
+ templateMap[tmplStruct.Name] = templateManagerRender{
+ Main: filepath.Base(tmplStruct.Files[0]),
+ Tmpl: tmpl,
+ }
+ }
+
+ return &TemplateManager{
+ templates: templateMap,
+ }, nil
+}
+
+func (tm *TemplateManager) Render(name string, data any, files ...string) ([]byte, error) {
+ tmpl, exists := tm.templates[name]
+ if !exists {
+ return nil, fmt.Errorf("template %s not found", name)
+ }
+
+ var err error
+ var tempTmpl *template.Template
+ var mainTmpl string = tmpl.Main
+ if len(files) == 0 {
+ if mainTmpl == "" {
+ return []byte{}, nil
+ }
+ tempTmpl = tmpl.Tmpl
+ } else {
+ tempTmpl, err = tmpl.Tmpl.Clone()
+ if err != nil {
+ return nil, fmt.Errorf("couldn't clone existing template for rendering: %w", err)
+ }
+ tempTmpl, err = tempTmpl.ParseFiles(files...)
+ if err != nil {
+ return nil, fmt.Errorf("couldn't include additional files in template rendering: %w", err)
+ }
+ if mainTmpl == "" {
+ mainTmpl = filepath.Base(files[0])
+ }
+ }
+
+ var buf bytes.Buffer
+ err = tempTmpl.ExecuteTemplate(&buf, mainTmpl, data)
+ return buf.Bytes(), err
+}
+
+func (tm *TemplateManager) Add(name string, files ...string) error {
+ tmpl := template.New(name).Funcs(templateFuncMap)
+
+ if len(files) == 0 {
+ tm.templates[name] = templateManagerRender{
+ Main: "",
+ Tmpl: tmpl,
+ }
+ return nil
+ }
+
+ tmpl, err := tmpl.ParseFiles(files...)
+ if err != nil {
+ return fmt.Errorf("failed to add template into manager: %w", err)
+ }
+
+ tm.templates[name] = templateManagerRender{
+ Main: filepath.Base(files[0]),
+ Tmpl: tmpl,
+ }
+
+ return nil
+}