From 8a2319033eb29e4931a72910e41116c0d850b155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lilian=20J=C3=B3nsd=C3=B3ttir?= Date: Tue, 23 Jan 2024 16:10:15 -0800 Subject: [PATCH] refactor how template data is handled + load template data from file Generating template data is now handled by templatedata instead of handlers. Renderer doesn't recieve any data, but now asks for data from templatedata. Additionally, template data is loaded from file (too lazy to split that into its own commit). Templates in ./templates/name.page.tmpl will have data loaded from ./templates/name.page.json --- internal/handlers/handlers.go | 28 +------------- internal/models/templatedata.go | 65 +++++++++++++++++++++++++++++---- internal/render/render.go | 19 ++++++++-- templates/about.page.tmpl | 45 +++++++---------------- templates/data/about.page.json | 46 +++++++++++++++++++++++ 5 files changed, 134 insertions(+), 69 deletions(-) create mode 100644 templates/data/about.page.json diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index 9682569..8617a17 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -2,10 +2,8 @@ package handlers import ( "net/http" - "time" "git.burning.moe/celediel/burning.moe/internal/config" - "git.burning.moe/celediel/burning.moe/internal/models" "git.burning.moe/celediel/burning.moe/internal/render" ) @@ -36,33 +34,11 @@ func Initialise(a *config.AppConfig) { app = a } -// makeBasicTemplateData creates a blank TemplateData containing only the -// time the related template was generated -func makeBasicTemplateData(name string) models.TemplateData { - var strMap map[string]string - if cacheItem, ok := app.TemplateCache.Cache[name]; ok { - strMap = map[string]string{ - "GeneratedAt": cacheItem.GeneratedAt.Format(time.UnixDate), - } - } else { - strMap = map[string]string{ - "GeneratedAt": time.Now().Format(time.UnixDate), - } - } - - templateData := models.TemplateData{ - StringMap: strMap, - } - return templateData -} - -// makeBasicHandler creates a basic handler that builds from a .page.tmpl -// file, and sends only the time the template was generated as TemplateData +// makeBasicHandler returns a simple handler that renders a template from `name`.page.tmpl func makeBasicHandler(name string) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { app.Logger.Infof("Got request for %s page", name) pageName := name + ".page.tmpl" - templateData := makeBasicTemplateData(pageName) - render.RenderTemplate(w, pageName, &templateData) + render.RenderTemplate(w, pageName) } } diff --git a/internal/models/templatedata.go b/internal/models/templatedata.go index 7ea43b2..82e8c22 100644 --- a/internal/models/templatedata.go +++ b/internal/models/templatedata.go @@ -1,14 +1,63 @@ package models +import ( + "encoding/json" + "html/template" + "os" + "strings" + "time" +) + +const dataDir string = "./templates/data/" + +type Link struct { + Href template.URL + Text string + Icon template.URL +} + // TemplateData holds data sent from handlers to templates. type TemplateData struct { - StringMap map[string]string - IntMap map[string]int - FloatMap map[string]float32 - Data map[string]interface{} - CSRFToken string - Flash string - Warning string - Error string + StringMap map[string]string `json:"stringMap"` + IntMap map[string]int `json:"intMap"` + FloatMap map[string]float32 `json:"floatMap"` + LinkMap map[string][]Link `json:"linkMap"` + Data map[string]interface{} `json:"data"` + CSRFToken string `json:"csrftoken"` + Flash string `json:"flash"` + Warning string `json:"warning"` + Error string `json:"error"` } +// makeBasicTemplateData creates a blank TemplateData containing only the +// time the related template was generated +func MakeBasicTemplateData(when time.Time) TemplateData { + strMap := map[string]string{ + "GeneratedAt": when.Format(time.UnixDate), + } + + templateData := TemplateData{ + StringMap: strMap, + } + return templateData +} + +// LoadTemplateData loads template data from file. If that +// fails, it returns an empty TemplateData and an error +func LoadTemplateData(page string) (TemplateData, error) { + // TODO: load from something other than JSON + var data *TemplateData + output := dataDir + strings.ReplaceAll(page, "tmpl", "json") + + file, err := os.ReadFile(output) + if err != nil { + return TemplateData{}, err + } + + err = json.Unmarshal(file, &data) + if err != nil { + return TemplateData{}, err + } + + return *data, nil +} diff --git a/internal/render/render.go b/internal/render/render.go index 7f648cd..fbbaf4e 100644 --- a/internal/render/render.go +++ b/internal/render/render.go @@ -81,7 +81,7 @@ func GenerateNewTemplateCache() (models.TemplateCache, error) { } // RenderTemplate renders requested template (t), pulling from cache. -func RenderTemplate(w http.ResponseWriter, filename string, data *models.TemplateData) { +func RenderTemplate(w http.ResponseWriter, filename string) { if !app.UseCache { c, err := GenerateNewTemplateCache() if err != nil { @@ -102,10 +102,23 @@ func RenderTemplate(w http.ResponseWriter, filename string, data *models.Templat template = app.TemplateCache.Cache[filename] } + // Get template data from file, or generate simple + data, err := models.LoadTemplateData(filename) + if err == nil { + app.Logger.Debug(fmt.Sprintf("Loaded data for template %s.", filename), "data", data) + if _, ok := data.StringMap["GeneratedAt"]; !ok { + data.StringMap["GeneratedAt"] = app.TemplateCache.Cache[filename].GeneratedAt.Format(time.UnixDate) + } + } else { + app.Logger.Info(fmt.Sprintf("Loading template data for %s failed, using default template data.", filename), "err", err) + data = models.MakeBasicTemplateData(template.GeneratedAt) + } + l := data.LinkMap["Personal"] + app.Logger.Debugf("%[1]v is %[1]T", l) + // Execute templates in a new buffer buf := new(bytes.Buffer) - err := template.Template.Execute(buf, data) - + err = template.Template.Execute(buf, data) if err != nil { app.Logger.Fatal(fmt.Sprintf("Error executing template %s! Goodbye!", filename), "err", err) } diff --git a/templates/about.page.tmpl b/templates/about.page.tmpl index 779a70e..626f065 100644 --- a/templates/about.page.tmpl +++ b/templates/about.page.tmpl @@ -4,46 +4,27 @@

celediel

- she/her, 1989, queer anarchist, self-taught aspiring developer + {{ index .StringMap "about" }} -

links

- - - matrix -
- - - - lemmy -
- - - - self-hosted git -
- - - - github +

links

+ {{ range (index .LinkMap "Personal") }} +
+ + {{ .Text }}
+ {{ end }}

hosted apps

- - - self-hosted git + {{ range (index .LinkMap "HostedApps") }} + + + {{ .Text }}
- - - wastebin -
- - - gist - -

+ {{ end }} +
back
{{ end -}} diff --git a/templates/data/about.page.json b/templates/data/about.page.json new file mode 100644 index 0000000..8fe7045 --- /dev/null +++ b/templates/data/about.page.json @@ -0,0 +1,46 @@ +{ + "StringMap": { + "about": "she/her, 1989, queer anarchist, self-taught aspiring developer and sysadmin" + }, + "LinkMap": { + "Personal": [ + { + "href": "https://matrix.to/#/@celediel:burning.moe", + "text": "matrix", + "icon": "tabler:brand-matrix" + }, + { + "href": "https://slrpnk.net/u/Celediel", + "text": "lemmy", + "icon": "simple-icons:lemmy" + }, + { + "href": "https://git.burning.moe/celediel", + "text": "self-hosted git", + "icon": "mdi:git" + }, + { + "href": "https://github.com/celediel", + "text": "github", + "icon": "bi:github" + } + ], + "HostedApps": [ + { + "href": "https://git.burning.moe/", + "text": "self-hosted git", + "icon": "mdi:git" + }, + { + "href": "https://bin.burning.moe/", + "text": "wastebin", + "icon": "fluent:bin-recycle-20-filled" + }, + { + "href": "https://gist.burning.moe/", + "text": "gist", + "icon": "carbon:paste" + } + ] + } +} \ No newline at end of file