You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
2.5 KiB
117 lines
2.5 KiB
package root
|
|
|
|
import (
|
|
"embed"
|
|
"fmt"
|
|
"html/template"
|
|
"io/fs"
|
|
"log"
|
|
"path/filepath"
|
|
"time"
|
|
)
|
|
|
|
//go:embed templates static/*
|
|
var webAssetsFS embed.FS
|
|
|
|
var WebTemplates *template.Template
|
|
|
|
// Custom helper functions for templates
|
|
var funcMap = template.FuncMap{
|
|
"pageContent": func(name string) string {
|
|
// This allows us to reference specific content blocks
|
|
return "{{template \"" + name + "-content\" .}}"
|
|
},
|
|
"add": func(a, b int) int {
|
|
return a + b
|
|
},
|
|
"subtract": func(a, b int) int {
|
|
return a - b
|
|
},
|
|
"div": func(a int64, b float64) float64 {
|
|
return float64(a) / b
|
|
},
|
|
"sequence": func(start, end int) []int {
|
|
if start > end {
|
|
return []int{}
|
|
}
|
|
result := make([]int, end-start+1)
|
|
for i := range result {
|
|
result[i] = start + i
|
|
}
|
|
return result
|
|
},
|
|
"formatDuration": func(d time.Duration) string {
|
|
seconds := d.Seconds()
|
|
if seconds < 60 {
|
|
return fmt.Sprintf("%.2fs", seconds)
|
|
} else if seconds < 3600 {
|
|
minutes := int(seconds) / 60
|
|
remainingSeconds := seconds - float64(minutes*60)
|
|
return fmt.Sprintf("%dm %.2fs", minutes, remainingSeconds)
|
|
} else {
|
|
hours := int(seconds) / 3600
|
|
remainingMinutes := int(seconds) % 3600 / 60
|
|
remainingSeconds := seconds - float64(hours*3600) - float64(remainingMinutes*60)
|
|
return fmt.Sprintf("%dh %dm %.2fs", hours, remainingMinutes, remainingSeconds)
|
|
}
|
|
},
|
|
}
|
|
|
|
// InitializeWebTemplates parses all HTML templates in the embedded filesystem
|
|
func InitializeWebTemplates() error {
|
|
var err error
|
|
WebTemplates, err = parseWebTemplates()
|
|
return err
|
|
}
|
|
|
|
func parseWebTemplates() (*template.Template, error) {
|
|
tmpl := template.New("").Funcs(funcMap)
|
|
|
|
// First collect all template paths
|
|
var templatePaths []string
|
|
err := fs.WalkDir(webAssetsFS, "templates", func(path string, d fs.DirEntry, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if d.IsDir() {
|
|
return nil
|
|
}
|
|
|
|
if filepath.Ext(path) != ".html" {
|
|
return nil
|
|
}
|
|
|
|
templatePaths = append(templatePaths, path)
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Process each template
|
|
for _, path := range templatePaths {
|
|
log.Printf("Parsing template: %s", path)
|
|
|
|
content, err := webAssetsFS.ReadFile(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
filename := filepath.Base(path)
|
|
name := filename
|
|
|
|
_, err = tmpl.New(name).Parse(string(content))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return tmpl, nil
|
|
}
|
|
|
|
// GetStaticFS provides access to the static assets filesystem for serving CSS and other static files
|
|
func GetStaticFS() (fs.FS, error) {
|
|
return fs.Sub(webAssetsFS, "static")
|
|
}
|
|
|