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
This commit is contained in:
Lilian Jónsdóttir 2024-01-23 16:10:15 -08:00
parent ffe303f1c6
commit 8a2319033e
5 changed files with 134 additions and 69 deletions

View file

@ -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)
}
}

View file

@ -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
}

View file

@ -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)
}

View file

@ -4,46 +4,27 @@
<span id="words">
<h4>celediel</h4>
<span id="bigwords">
she/her, 1989, queer anarchist, self-taught aspiring developer
{{ index .StringMap "about" }}
</span>
<h4>links</h4>
<!-- personal links -->
<a href="https://matrix.to/#/@celediel:burning.moe">
<span class="iconify" data-icon="tabler:brand-matrix"></span>
matrix
</a><br />
<a href="https://slrpnk.net/u/Celediel">
<span class="iconify" data-icon="simple-icons:lemmy"></span>
lemmy
</a><br />
<a href="https://git.burning.moe/celediel">
<span class="iconify" data-icon="mdi:git"></span>
self-hosted git
</a><br />
<a href="https://github.com/celediel">
<span class="iconify" data-icon="bi:github"></span>
github
<h4>links</h4>
{{ range (index .LinkMap "Personal") }}
<a href="{{ .Href }}">
<span class="iconify" data-icon="{{ .Icon }}"></span>
{{ .Text }}
</a><br />
{{ end }}
<!-- web app links -->
<h4>hosted apps</h4>
<a href="https://git.burning.moe/">
<span class="iconify" data-icon="mdi:git"></span>
self-hosted git
{{ range (index .LinkMap "HostedApps") }}
<a href="{{ .Href }}">
<span class="iconify" data-icon="{{ .Icon }}"></span>
{{ .Text }}
</a><br />
<a href="https://bin.burning.moe/">
<span class="iconify" data-icon="fluent:bin-recycle-20-filled"></span>
wastebin
</a><br />
<a href="https://gist.burning.moe/">
<span class="iconify" data-icon="carbon:paste"></span>
gist
</a>
<br /><br />
{{ end }}
<br />
<a href="/">back</a>
</span>
{{ end -}}

View file

@ -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"
}
]
}
}