load template data from json, toml, or yaml
because why not, the required modules were already included as dependencies for other things nothing new in go.mod, just indirect -> direct
This commit is contained in:
parent
e446e6520b
commit
16397fce66
6
go.mod
6
go.mod
|
@ -3,16 +3,17 @@ module git.burning.moe/celediel/burning.moe
|
||||||
go 1.21.5
|
go 1.21.5
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/BurntSushi/toml v1.3.2
|
||||||
|
github.com/charmbracelet/log v0.3.1
|
||||||
github.com/go-chi/chi/v5 v5.0.11
|
github.com/go-chi/chi/v5 v5.0.11
|
||||||
github.com/ilyakaznacheev/cleanenv v1.5.0
|
github.com/ilyakaznacheev/cleanenv v1.5.0
|
||||||
github.com/magefile/mage v1.15.0
|
github.com/magefile/mage v1.15.0
|
||||||
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||||
github.com/charmbracelet/lipgloss v0.9.1 // indirect
|
github.com/charmbracelet/lipgloss v0.9.1 // indirect
|
||||||
github.com/charmbracelet/log v0.3.1 // indirect
|
|
||||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||||
github.com/joho/godotenv v1.5.1 // indirect
|
github.com/joho/godotenv v1.5.1 // indirect
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||||
|
@ -23,6 +24,5 @@ require (
|
||||||
github.com/rivo/uniseg v0.2.0 // indirect
|
github.com/rivo/uniseg v0.2.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
||||||
golang.org/x/sys v0.13.0 // indirect
|
golang.org/x/sys v0.13.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
|
||||||
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect
|
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect
|
||||||
)
|
)
|
||||||
|
|
7
go.sum
7
go.sum
|
@ -7,6 +7,8 @@ github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1
|
||||||
github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I=
|
github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I=
|
||||||
github.com/charmbracelet/log v0.3.1 h1:TjuY4OBNbxmHWSwO3tosgqs5I3biyY8sQPny/eCMTYw=
|
github.com/charmbracelet/log v0.3.1 h1:TjuY4OBNbxmHWSwO3tosgqs5I3biyY8sQPny/eCMTYw=
|
||||||
github.com/charmbracelet/log v0.3.1/go.mod h1:OR4E1hutLsax3ZKpXbgUqPtTjQfrh1pG3zwHGWuuq8g=
|
github.com/charmbracelet/log v0.3.1/go.mod h1:OR4E1hutLsax3ZKpXbgUqPtTjQfrh1pG3zwHGWuuq8g=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/go-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA=
|
github.com/go-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA=
|
||||||
github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||||
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
||||||
|
@ -28,14 +30,19 @@ github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
|
||||||
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
|
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
|
||||||
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
|
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
|
||||||
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
|
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
|
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
|
||||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
|
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|
|
@ -2,31 +2,37 @@ package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"html/template"
|
"html/template"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/BurntSushi/toml"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
const dataDir string = "./templates/data/"
|
const dataDir string = "./templates/data/"
|
||||||
|
|
||||||
|
// in order of precedence
|
||||||
|
var dataExtensions = [4]string{"yml", "yaml", "toml", "json"}
|
||||||
|
|
||||||
type Link struct {
|
type Link struct {
|
||||||
Href template.URL
|
Href, Icon template.URL
|
||||||
Text string
|
Text string
|
||||||
Icon template.URL
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TemplateData holds data sent from handlers to templates.
|
// TemplateData holds data sent from handlers to templates.
|
||||||
type TemplateData struct {
|
type TemplateData struct {
|
||||||
StringMap map[string]string `json:"stringMap"`
|
StringMap map[string]string `json:"StringMap" yaml:"StringMap" toml:"StringMap"`
|
||||||
IntMap map[string]int `json:"intMap"`
|
IntMap map[string]int `json:"IntMap" yaml:"IntMap" toml:"IntMap"`
|
||||||
FloatMap map[string]float32 `json:"floatMap"`
|
FloatMap map[string]float32 `json:"FloatMap" yaml:"FloatMap" toml:"FloatMap"`
|
||||||
LinkMap map[string][]Link `json:"linkMap"`
|
LinkMap map[string][]Link `json:"LinkMap" yaml:"LinkMap" toml:"LinkMap"`
|
||||||
Data map[string]interface{} `json:"data"`
|
Data map[string]interface{} `json:"Data" yaml:"Data" toml:"Data"`
|
||||||
CSRFToken string `json:"csrftoken"`
|
CSRFToken string `json:"Csrftoken" yaml:"Csrftoken" toml:"Csrftoken"`
|
||||||
Flash string `json:"flash"`
|
Flash string `json:"Flash" yaml:"Flash" toml:"Flash"`
|
||||||
Warning string `json:"warning"`
|
Warning string `json:"Warning" yaml:"Warning" toml:"Warning"`
|
||||||
Error string `json:"error"`
|
Error string `json:"Error" yaml:"Error" toml:"Error"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeBasicTemplateData creates a blank TemplateData containing only the
|
// makeBasicTemplateData creates a blank TemplateData containing only the
|
||||||
|
@ -45,19 +51,47 @@ func MakeBasicTemplateData(when time.Time) TemplateData {
|
||||||
// LoadTemplateData loads template data from file. If that
|
// LoadTemplateData loads template data from file. If that
|
||||||
// fails, it returns an empty TemplateData and an error
|
// fails, it returns an empty TemplateData and an error
|
||||||
func LoadTemplateData(page string) (TemplateData, error) {
|
func LoadTemplateData(page string) (TemplateData, error) {
|
||||||
// TODO: load from something other than JSON
|
var data TemplateData
|
||||||
var data *TemplateData
|
output := dataDir + strings.ReplaceAll(page, "tmpl", "")
|
||||||
output := dataDir + strings.ReplaceAll(page, "tmpl", "json")
|
|
||||||
|
|
||||||
file, err := os.ReadFile(output)
|
for _, extension := range dataExtensions {
|
||||||
if err != nil {
|
if info, err := os.Stat(output + extension); err == nil && !info.IsDir() {
|
||||||
return TemplateData{}, err
|
data, err = loadFromFile(output, extension)
|
||||||
|
if err == nil {
|
||||||
|
// don't try anymore files
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(file, &data)
|
// couldn't load anything from file
|
||||||
if err != nil {
|
return TemplateData{}, errors.New("Couldn't load data from file")
|
||||||
return TemplateData{}, err
|
}
|
||||||
}
|
|
||||||
|
// loadFromFile loads TemplateData from the specified filetype (yaml, toml, or json)
|
||||||
return *data, nil
|
func loadFromFile(filename, filetype string) (TemplateData, error) {
|
||||||
|
var data TemplateData
|
||||||
|
file, err := os.ReadFile(filename + filetype)
|
||||||
|
if err != nil {
|
||||||
|
return TemplateData{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch filetype {
|
||||||
|
case "json":
|
||||||
|
err = json.Unmarshal(file, &data)
|
||||||
|
if err != nil {
|
||||||
|
return TemplateData{}, err
|
||||||
|
}
|
||||||
|
case "toml":
|
||||||
|
err = toml.Unmarshal(file, &data)
|
||||||
|
if err != nil {
|
||||||
|
return TemplateData{}, err
|
||||||
|
}
|
||||||
|
case "yaml":
|
||||||
|
err = yaml.Unmarshal(file, &data)
|
||||||
|
if err != nil {
|
||||||
|
return TemplateData{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
{
|
|
||||||
"StringMap": {
|
|
||||||
"about": "she/her, 1989, queer anarchist and 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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
26
templates/data/about.page.yaml
Normal file
26
templates/data/about.page.yaml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
StringMap:
|
||||||
|
about: she/her, 1989, queer anarchist and 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
|
Loading…
Reference in a new issue