140 lines
3.4 KiB
Go
140 lines
3.4 KiB
Go
|
|
package templates
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
"embed"
|
||
|
|
"encoding/json"
|
||
|
|
"html/template"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
//go:embed *.html
|
||
|
|
var templateFS embed.FS
|
||
|
|
|
||
|
|
var funcMap = template.FuncMap{
|
||
|
|
"safeHTML": func(s string) template.HTML { return template.HTML(s) },
|
||
|
|
"json": func(v any) string { b, _ := json.Marshal(v); return string(b) },
|
||
|
|
"or": func(a, b any) any {
|
||
|
|
if a != nil && a != "" {
|
||
|
|
return a
|
||
|
|
}
|
||
|
|
return b
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
var fontURLs = map[string]string{
|
||
|
|
"system": "",
|
||
|
|
"inter": "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap",
|
||
|
|
"georgia": "",
|
||
|
|
"merriweather": "https://fonts.googleapis.com/css2?family=Merriweather:wght@400;700&display=swap",
|
||
|
|
"source-serif": "https://fonts.googleapis.com/css2?family=Source+Serif+4:wght@400;600;700&display=swap",
|
||
|
|
"jetbrains-mono": "https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap",
|
||
|
|
}
|
||
|
|
|
||
|
|
var fontFamilies = map[string]string{
|
||
|
|
"system": "system-ui, -apple-system, sans-serif",
|
||
|
|
"inter": "'Inter', system-ui, sans-serif",
|
||
|
|
"georgia": "Georgia, 'Times New Roman', serif",
|
||
|
|
"merriweather": "'Merriweather', Georgia, serif",
|
||
|
|
"source-serif": "'Source Serif 4', Georgia, serif",
|
||
|
|
"jetbrains-mono": "'JetBrains Mono', 'Fira Code', monospace",
|
||
|
|
}
|
||
|
|
|
||
|
|
func GetFontURL(fontKey string) string {
|
||
|
|
if url, ok := fontURLs[fontKey]; ok {
|
||
|
|
return url
|
||
|
|
}
|
||
|
|
return ""
|
||
|
|
}
|
||
|
|
|
||
|
|
func GetFontFamily(fontKey string) string {
|
||
|
|
if family, ok := fontFamilies[fontKey]; ok {
|
||
|
|
return family
|
||
|
|
}
|
||
|
|
return fontFamilies["system"]
|
||
|
|
}
|
||
|
|
|
||
|
|
var homeTemplate, blogTemplate, postTemplate *template.Template
|
||
|
|
|
||
|
|
func init() {
|
||
|
|
homeTemplate = template.Must(template.New("").Funcs(funcMap).ParseFS(templateFS, "base.html", "home.html"))
|
||
|
|
blogTemplate = template.Must(template.New("").Funcs(funcMap).ParseFS(templateFS, "base.html", "blog.html"))
|
||
|
|
postTemplate = template.Must(template.New("").Funcs(funcMap).ParseFS(templateFS, "base.html", "post.html"))
|
||
|
|
}
|
||
|
|
|
||
|
|
type PageData struct {
|
||
|
|
Title string
|
||
|
|
Description string
|
||
|
|
CanonicalURL string
|
||
|
|
OGType string
|
||
|
|
OGImage string
|
||
|
|
NoIndex bool
|
||
|
|
SiteName string
|
||
|
|
Year int
|
||
|
|
FontURL string
|
||
|
|
FontFamily string
|
||
|
|
StructuredData template.JS
|
||
|
|
Settings map[string]any
|
||
|
|
ShowBadge bool
|
||
|
|
}
|
||
|
|
|
||
|
|
type HomeData struct {
|
||
|
|
PageData
|
||
|
|
Posts []PostSummary
|
||
|
|
HasMore bool
|
||
|
|
}
|
||
|
|
|
||
|
|
type BlogData struct {
|
||
|
|
PageData
|
||
|
|
Posts []PostSummary
|
||
|
|
PrevPage string
|
||
|
|
NextPage string
|
||
|
|
}
|
||
|
|
|
||
|
|
type PostData struct {
|
||
|
|
PageData
|
||
|
|
Post PostDetail
|
||
|
|
ContentHTML template.HTML
|
||
|
|
InteractionConfig map[string]any
|
||
|
|
}
|
||
|
|
|
||
|
|
type PostSummary struct {
|
||
|
|
Slug string
|
||
|
|
Title string
|
||
|
|
Description string
|
||
|
|
Date time.Time
|
||
|
|
}
|
||
|
|
|
||
|
|
type PostDetail struct {
|
||
|
|
Slug string
|
||
|
|
Title string
|
||
|
|
Description string
|
||
|
|
CoverImage string
|
||
|
|
Date time.Time
|
||
|
|
Tags []string
|
||
|
|
}
|
||
|
|
|
||
|
|
func RenderHome(data HomeData) ([]byte, error) {
|
||
|
|
var buf bytes.Buffer
|
||
|
|
if err := homeTemplate.ExecuteTemplate(&buf, "base.html", data); err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
return buf.Bytes(), nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func RenderBlog(data BlogData) ([]byte, error) {
|
||
|
|
var buf bytes.Buffer
|
||
|
|
if err := blogTemplate.ExecuteTemplate(&buf, "base.html", data); err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
return buf.Bytes(), nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func RenderPost(data PostData) ([]byte, error) {
|
||
|
|
var buf bytes.Buffer
|
||
|
|
if err := postTemplate.ExecuteTemplate(&buf, "base.html", data); err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
return buf.Bytes(), nil
|
||
|
|
}
|