diff --git a/html/embed.go b/html/embed.go
index 4faac68b..03ba01f5 100644
--- a/html/embed.go
+++ b/html/embed.go
@@ -25,62 +25,121 @@ import (
var embeddedFiles embed.FS
type templateSystemEmbed struct {
- allTemplates *template.Template
nameToTemplate map[string]*template.Template
sourceFS fs.FS
}
+func newTemplateSystemEmbed() (templateSystemEmbed, error) {
+ ts := templateSystemEmbed{
+ sourceFS: embeddedFiles,
+ nameToTemplate: make(map[string]*template.Template),
+ }
+
+ // Load all templates
+ if err := ts.loadAll(); err != nil {
+ return ts, err
+ }
+
+ return ts, nil
+}
func (ts templateSystemEmbed) loadAll() error {
- ts.nameToTemplate = make(map[string]*template.Template, 0)
- err := fs.WalkDir(ts.sourceFS, "template", func(path string, d fs.DirEntry, err error) error {
+ // Then, parse all remaining templates into their named slots, adding the shared stuff
+ page_subdirs := []string{"template/sync"}
+ for _, subdir := range page_subdirs {
+ err := ts.loadTemplateSubdir(subdir)
if err != nil {
- return err
+ return fmt.Errorf("Failed to load subdir '%s': %w", subdir, err)
}
-
- if d.IsDir() {
- return nil
- }
- short_path := removeLeadingDir(path)
-
- new_t, err := loadTemplateEmbedded(ts.sourceFS, short_path)
- if err != nil {
- return fmt.Errorf("Failed to add load template '%s': %w", short_path, err)
- }
- _, err = ts.allTemplates.AddParseTree(new_t.Name(), new_t.Tree)
- if err != nil {
- return fmt.Errorf("Failed to add parsed template '%s': %w", path, err)
- }
- ts.nameToTemplate[short_path] = new_t
- log.Debug().Str("path", path).Str("short_path", short_path).Msg("Loaded template")
- return nil
- })
- if err != nil {
- return fmt.Errorf("failed to load embeded templates: %w", err)
}
return nil
}
+
+func (ts templateSystemEmbed) loadTemplateSubdir(subdir string) error {
+ err := fs.WalkDir(ts.sourceFS, subdir, func(path string, d fs.DirEntry, err error) error {
+ if err != nil || d.IsDir() {
+ return err
+ }
+
+ content, err := fs.ReadFile(ts.sourceFS, path)
+ if err != nil {
+ return fmt.Errorf("error reading template %s: %w", path, err)
+ }
+
+ new_t := template.New(path)
+ addFuncMap(new_t)
+ _, err = new_t.Parse(string(content))
+ if err != nil {
+ return fmt.Errorf("error parsing '%s': %w", path, err)
+ }
+ short_path := removeLeadingDir(path)
+ shared_template_holder := template.New("shared")
+ shared_subdirs := []string{"template/sync/component", "template/sync/layout"}
+ for _, shared_subdir := range shared_subdirs {
+ err := ts.addSubdirTemplates(shared_template_holder, shared_subdir)
+ if err != nil {
+ return fmt.Errorf("Failed to add subdir '%s' templates: %w", shared_subdir, err)
+ }
+ }
+ if shared_template_holder.Tree == nil {
+ return fmt.Errorf("shared template holder tree is nil")
+ }
+ _, err = new_t.AddParseTree(short_path, shared_template_holder.Tree)
+ if err != nil {
+ return fmt.Errorf("error adding shared parse tree to '%s': %w", path, err)
+ }
+ log.Debug().Str("path", short_path).Msg("Loaded page template")
+ return nil
+ })
+ return err
+}
+
+func (ts templateSystemEmbed) addSubdirTemplates(t *template.Template, subdir string) error {
+ var err error
+ log.Debug().Msg("Adding subdir templates")
+ err = fs.WalkDir(ts.sourceFS, subdir, func(path string, d fs.DirEntry, err error) error {
+ if err != nil || d.IsDir() {
+ return err
+ }
+
+ content, err := fs.ReadFile(ts.sourceFS, path)
+ if err != nil {
+ return fmt.Errorf("error reading template %s: %w", path, err)
+ }
+
+ new_t := template.New(path)
+ addFuncMap(new_t)
+ _, err = new_t.Parse(string(content))
+ if err != nil {
+ return fmt.Errorf("error parsing '%s': %w", path, err)
+ }
+ short_path := removeLeadingDir(path)
+ _, err = t.AddParseTree(short_path, new_t.Tree)
+ if err != nil {
+ return fmt.Errorf("error adding parse tree '%s': %w", path, err)
+ }
+ ts.nameToTemplate[short_path] = new_t
+ //log.Debug().Str("path", short_path).Msg("Loaded shared component template")
+ return nil
+ })
+ return err
+}
+
func (ts templateSystemEmbed) renderOrError(w http.ResponseWriter, template_name string, context interface{}) {
buf := &bytes.Buffer{}
- t, err := loadTemplateEmbedded(ts.sourceFS, template_name)
- if err != nil {
- log.Error().Err(err).Str("template_name", template_name).Msg("Failed to load embedded template")
- RespondError(w, "Failed to load template", err, http.StatusInternalServerError)
- return
+
+ // Execute the template directly from the pre-parsed set
+ templ, ok := ts.nameToTemplate[template_name]
+ if !ok {
+ log.Error().Str("template_name", template_name).Msg("Can't find template")
+ RespondError(w, "Failed to render template", nil, http.StatusInternalServerError)
}
- for name, templ := range ts.nameToTemplate {
- _, err := t.AddParseTree(name, templ.Tree)
- if err != nil {
- log.Error().Err(err).Str("name", name).Msg("Failed to add parse tree")
- RespondError(w, "Failed to add template", err, http.StatusInternalServerError)
- return
- }
- }
- err = t.ExecuteTemplate(buf, template_name, context)
+ err := templ.Execute(buf, context)
if err != nil {
- log.Error().Err(err).Str("template_name", template_name).Msg("Failed to render embedded template")
+ log.Error().Err(err).Str("template_name", template_name).Msg("Failed to render template")
RespondError(w, "Failed to render template", err, http.StatusInternalServerError)
return
}
+
buf.WriteTo(w)
}
func loadTemplateEmbedded(sourceFS fs.FS, path string) (*template.Template, error) {
diff --git a/html/filesystem.go b/html/filesystem.go
index 0862c0df..dcc76835 100644
--- a/html/filesystem.go
+++ b/html/filesystem.go
@@ -36,16 +36,15 @@ type templateSystemDisk struct {
func LoadTemplates() error {
_, err := os.Stat("html/template")
- if err == nil {
+ if err != nil {
templates = templateSystemDisk{
sourceFS: os.DirFS("./html/template"),
}
} else {
- templates = templateSystemEmbed{
- allTemplates: template.New("all"),
- sourceFS: embeddedFiles,
+ templates, err = newTemplateSystemEmbed()
+ if err != nil {
+ return fmt.Errorf("Failed to load embedded templates: %w", err)
}
- templates.loadAll()
}
return nil
}
diff --git a/html/template/sync/authenticated.html b/html/template/sync/layout/authenticated.html
similarity index 100%
rename from html/template/sync/authenticated.html
rename to html/template/sync/layout/authenticated.html
diff --git a/html/template/sync/base.html b/html/template/sync/layout/base.html
similarity index 100%
rename from html/template/sync/base.html
rename to html/template/sync/layout/base.html