Initial commit
This commit is contained in:
commit
c578b91c2d
46 files changed
+3241
No files matched your search
@@ -0,0 +1,90 @@
|
||||
package template
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
baseDir string
|
||||
cache map[string]*template.Template
|
||||
}
|
||||
|
||||
func createFuncMap() template.FuncMap {
|
||||
funcMap := template.FuncMap{
|
||||
"dict": func(pairs ...any) (map[string]any, error) {
|
||||
if len(pairs)%2 != 0 {
|
||||
return nil, fmt.Errorf("dict requires an even number of arguments")
|
||||
}
|
||||
m := make(map[string]any)
|
||||
for i := 0; i < len(pairs); i += 2 {
|
||||
key, ok := pairs[i].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("dict keys must be strings")
|
||||
}
|
||||
m[key] = pairs[i+1]
|
||||
}
|
||||
return m, nil
|
||||
},
|
||||
"default": func(fallback string, value any) any {
|
||||
if value == nil {
|
||||
return fallback
|
||||
}
|
||||
return value
|
||||
},
|
||||
}
|
||||
|
||||
return funcMap
|
||||
}
|
||||
|
||||
func NewService(uiDir string) (*Service, error) {
|
||||
cache := make(map[string]*template.Template)
|
||||
|
||||
uiFS := os.DirFS(uiDir)
|
||||
|
||||
funcMap := createFuncMap()
|
||||
|
||||
err := fs.WalkDir(uiFS, "pages", func(filePath string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if d.IsDir() {
|
||||
return nil
|
||||
}
|
||||
if !strings.HasSuffix(filePath, ".html") {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Key by the relative path under pages/, e.g. "auth/signin.html".
|
||||
relPath := strings.TrimPrefix(filePath, "pages/")
|
||||
|
||||
tmpl, err := template.New(path.Base(filePath)).Funcs(funcMap).ParseFS(uiFS, filePath, "layouts/*.html")
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't parse filesystem: %w", err)
|
||||
}
|
||||
cache[relPath] = tmpl
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't walk 'pages' in '%s': %w", uiDir, err)
|
||||
}
|
||||
|
||||
return &Service{
|
||||
baseDir: uiDir,
|
||||
cache: cache,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (e *Service) Render(w io.Writer, pageName string, data any) error {
|
||||
tmpl, ok := e.cache[pageName]
|
||||
if !ok {
|
||||
return fmt.Errorf("no such template: %s", pageName)
|
||||
}
|
||||
return tmpl.Execute(w, data)
|
||||
}
|
||||
Reference in new issue
Block a user