♻️ Refactored template utils map setup
This commit is contained in:
parent
6012945d06
commit
a475dacd60
|
@ -0,0 +1,42 @@
|
|||
package partial
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/fs"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Namespace struct {
|
||||
dir fs.FS
|
||||
funcMap template.FuncMap
|
||||
}
|
||||
|
||||
func New(dir fs.FS, funcMap template.FuncMap) *Namespace {
|
||||
return &Namespace{
|
||||
dir: dir,
|
||||
funcMap: funcMap,
|
||||
}
|
||||
}
|
||||
|
||||
func (ns *Namespace) Include(name string, data any) (template.HTML, error) {
|
||||
name = strings.TrimPrefix(filepath.Clean(name), "partials/")
|
||||
|
||||
if filepath.Ext(name) == "" {
|
||||
name += ".html"
|
||||
}
|
||||
|
||||
tpl, err := template.New(name).Funcs(ns.funcMap).ParseFS(ns.dir, name)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("cannot parse partial: %w", err)
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
if err = tpl.Execute(buf, data); err != nil {
|
||||
return "", fmt.Errorf("cannot execute partial: %w", err)
|
||||
}
|
||||
|
||||
return template.HTML(buf.String()), nil
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package templateutil
|
||||
package safe
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
@ -6,13 +6,23 @@ import (
|
|||
"reflect"
|
||||
)
|
||||
|
||||
type Namespace struct{}
|
||||
|
||||
var ErrSafeHTML error = errors.New("unsupported input type for SafeHTML")
|
||||
|
||||
func SafeHTML(v reflect.Value) (template.HTML, error) {
|
||||
func New() *Namespace {
|
||||
return &Namespace{}
|
||||
}
|
||||
|
||||
func (Namespace) HTML(v reflect.Value) (template.HTML, error) {
|
||||
switch v.Kind() {
|
||||
default:
|
||||
return "", ErrSafeHTML
|
||||
case reflect.Slice:
|
||||
if v.Elem().Kind() != reflect.Uint8 {
|
||||
return "", ErrSafeHTML
|
||||
}
|
||||
|
||||
return template.HTML(v.Bytes()), nil
|
||||
case reflect.String:
|
||||
return template.HTML(v.String()), nil
|
|
@ -0,0 +1,17 @@
|
|||
package string
|
||||
|
||||
import "strings"
|
||||
|
||||
type Namespace struct{}
|
||||
|
||||
func New() *Namespace {
|
||||
return &Namespace{}
|
||||
}
|
||||
|
||||
func (ns *Namespace) HasPrefix(s, prefix string) bool {
|
||||
return strings.HasPrefix(s, prefix)
|
||||
}
|
||||
|
||||
func (ns *Namespace) HasSuffix(s, suffix string) bool {
|
||||
return strings.HasSuffix(s, suffix)
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package templateutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/fs"
|
||||
|
||||
"source.toby3d.me/toby3d/home/internal/templateutil/partial"
|
||||
"source.toby3d.me/toby3d/home/internal/templateutil/safe"
|
||||
strings "source.toby3d.me/toby3d/home/internal/templateutil/string"
|
||||
)
|
||||
|
||||
type Function struct {
|
||||
Handler func(v ...any) any
|
||||
Methods template.FuncMap
|
||||
Name string
|
||||
}
|
||||
|
||||
func New(dir fs.FS) (template.FuncMap, error) {
|
||||
partials, err := fs.Sub(dir, "partials")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot substitute into partials subdirectory: %w", err)
|
||||
}
|
||||
|
||||
funcMap := make(template.FuncMap)
|
||||
funcs := make([]Function, 0)
|
||||
stringsNamespace := strings.New()
|
||||
funcs = append(funcs, Function{
|
||||
Name: "strings",
|
||||
Handler: func(v ...any) any { return stringsNamespace },
|
||||
Methods: template.FuncMap{
|
||||
"hasPrefix": stringsNamespace.HasPrefix,
|
||||
"hasSuffix": stringsNamespace.HasSuffix,
|
||||
},
|
||||
})
|
||||
safeNamespace := safe.New()
|
||||
funcs = append(funcs, Function{
|
||||
Name: "safe",
|
||||
Handler: func(v ...any) any { return safeNamespace },
|
||||
Methods: template.FuncMap{
|
||||
"safeHTML": safeNamespace.HTML,
|
||||
},
|
||||
})
|
||||
partialNamespace := partial.New(partials, funcMap)
|
||||
funcs = append(funcs, Function{
|
||||
Name: "partials",
|
||||
Handler: func(v ...any) any { return partialNamespace },
|
||||
Methods: template.FuncMap{
|
||||
"partial": partialNamespace.Include,
|
||||
},
|
||||
})
|
||||
|
||||
for _, f := range funcs {
|
||||
funcMap[f.Name] = f.Handler
|
||||
|
||||
for name, m := range f.Methods {
|
||||
funcMap[name] = m
|
||||
}
|
||||
}
|
||||
|
||||
return funcMap, nil
|
||||
}
|
Loading…
Reference in New Issue