120 lines
3.1 KiB
Go
120 lines
3.1 KiB
Go
package templates
|
|
|
|
import (
|
|
"embed"
|
|
"fmt"
|
|
"html/template"
|
|
"net/url"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.handmade.network/hmn/hmn/src/hmnurl"
|
|
"git.handmade.network/hmn/hmn/src/logging"
|
|
"github.com/Masterminds/sprig"
|
|
"github.com/teacat/noire"
|
|
)
|
|
|
|
//go:embed src
|
|
var templateFs embed.FS
|
|
var Templates map[string]*template.Template
|
|
|
|
var cachebust string
|
|
|
|
func Init() {
|
|
cachebust = fmt.Sprint(time.Now().Unix())
|
|
|
|
Templates = make(map[string]*template.Template)
|
|
|
|
files, _ := templateFs.ReadDir("src")
|
|
for _, f := range files {
|
|
if strings.HasSuffix(f.Name(), ".html") {
|
|
t := template.New(f.Name())
|
|
t = t.Funcs(sprig.FuncMap())
|
|
t = t.Funcs(HMNTemplateFuncs)
|
|
t, err := t.ParseFS(templateFs, "src/layouts/*.html", "src/include/*.html", "src/"+f.Name())
|
|
if err != nil {
|
|
logging.Fatal().Str("filename", f.Name()).Err(err).Msg("failed to parse template")
|
|
}
|
|
|
|
Templates[f.Name()] = t
|
|
} else if strings.HasSuffix(f.Name(), ".css") {
|
|
t := template.New(f.Name())
|
|
t = t.Funcs(sprig.FuncMap())
|
|
t = t.Funcs(HMNTemplateFuncs)
|
|
t, err := t.ParseFS(templateFs, "src/"+f.Name())
|
|
if err != nil {
|
|
logging.Fatal().Str("filename", f.Name()).Err(err).Msg("failed to parse template")
|
|
}
|
|
|
|
Templates[f.Name()] = t
|
|
}
|
|
}
|
|
}
|
|
|
|
func names(ts []*template.Template) []string {
|
|
result := make([]string, len(ts))
|
|
for i, t := range ts {
|
|
result[i] = t.Name()
|
|
}
|
|
return result
|
|
}
|
|
|
|
var HMNTemplateFuncs = template.FuncMap{
|
|
"brighten": func(hexColor string, amount float64) (string, error) {
|
|
if len(hexColor) < 6 {
|
|
return "", fmt.Errorf("couldn't brighten invalid hex color: %v", hexColor)
|
|
}
|
|
return noire.NewHex(hexColor).Tint(amount).Hex(), nil
|
|
},
|
|
"cachebust": func() string {
|
|
return cachebust
|
|
},
|
|
"darken": func(hexColor string, amount float64) (string, error) {
|
|
if len(hexColor) < 6 {
|
|
return "", fmt.Errorf("couldn't darken invalid hex color: %v", hexColor)
|
|
}
|
|
return noire.NewHex(hexColor).Shade(amount).Hex(), nil
|
|
},
|
|
"projecturl": func(url string) string {
|
|
return hmnurl.Url(url, nil) // TODO: Use project subdomain
|
|
},
|
|
"projecturlq": func(url string, query string) string {
|
|
absUrl := hmnurl.Url(url, nil)
|
|
return fmt.Sprintf("%s?%s", absUrl, query) // TODO: Use project subdomain
|
|
},
|
|
"query": func(args ...string) string {
|
|
query := url.Values{}
|
|
for i := 0; i < len(args); i += 2 {
|
|
query.Set(args[i], args[i+1])
|
|
}
|
|
return query.Encode()
|
|
},
|
|
"static": func(filepath string) string {
|
|
return hmnurl.StaticUrl(filepath, []hmnurl.Q{{"v", cachebust}})
|
|
},
|
|
"staticnobust": func(filepath string) string {
|
|
return hmnurl.StaticUrl(filepath, nil)
|
|
},
|
|
"statictheme": func(theme string, filepath string) string {
|
|
return hmnurl.StaticThemeUrl(filepath, theme, []hmnurl.Q{{"v", cachebust}})
|
|
},
|
|
"staticthemenobust": func(theme string, filepath string) string {
|
|
return hmnurl.StaticThemeUrl(filepath, theme, nil)
|
|
},
|
|
"url": func(url string) string {
|
|
return hmnurl.Url(url, nil)
|
|
},
|
|
"urlq": func(url string, query string) string {
|
|
absUrl := hmnurl.Url(url, nil)
|
|
return fmt.Sprintf("%s?%s", absUrl, query)
|
|
},
|
|
}
|
|
|
|
type ErrInvalidHexColor struct {
|
|
color string
|
|
}
|
|
|
|
func (e ErrInvalidHexColor) Error() string {
|
|
return fmt.Sprintf("invalid hex color: %s", e.color)
|
|
}
|