88 lines
1.8 KiB
Go
88 lines
1.8 KiB
Go
package tmpls
|
|
|
|
import (
|
|
"errors"
|
|
"html/template"
|
|
"io/fs"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin/render"
|
|
)
|
|
|
|
var ErrNoTmpl = errors.New("no such template in map")
|
|
|
|
// TmplMap is a map of templates that implements
|
|
// the render.HTMLRender interface
|
|
type Map map[string]*template.Template
|
|
|
|
// Instance returns a Tmpl instance for the given template
|
|
func (m Map) Instance(name string, data interface{}) render.Render {
|
|
tmpl, ok := m[name]
|
|
if !ok {
|
|
return nil
|
|
}
|
|
return Tmpl{
|
|
Template: tmpl,
|
|
data: data,
|
|
}
|
|
}
|
|
|
|
// Tmpl implements the render.Render interface
|
|
type Tmpl struct {
|
|
*template.Template
|
|
data interface{}
|
|
}
|
|
|
|
// Render renders the template to response writer
|
|
func (t Tmpl) Render(res http.ResponseWriter) error {
|
|
if t.Template == nil {
|
|
return ErrNoTmpl
|
|
}
|
|
return t.Execute(res, t.data)
|
|
}
|
|
|
|
// WriteContentType sets content type to HTML
|
|
func (t Tmpl) WriteContentType(res http.ResponseWriter) {
|
|
res.Header().Set("Content-Type", "text/html; charset=utf-8")
|
|
}
|
|
|
|
func FromFS(f fs.FS, root, ext string, fm template.FuncMap) (Map, error) {
|
|
tmpls := Map{}
|
|
err := fs.WalkDir(f, root, func(path string, d fs.DirEntry, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if d.IsDir() || path == filepath.Join(root, "base"+ext) {
|
|
return nil
|
|
}
|
|
|
|
tmplName := strings.TrimPrefix(path, root+"/")
|
|
tmplName = strings.TrimSuffix(tmplName, ext)
|
|
|
|
tmpl := template.New(filepath.Base(path))
|
|
|
|
if fm != nil {
|
|
tmpl = tmpl.Funcs(fm)
|
|
}
|
|
|
|
tmpl, err = tmpl.ParseFS(f, path, filepath.Join(root, "base"+ext))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tmpls[tmplName] = tmpl
|
|
|
|
return nil
|
|
})
|
|
return tmpls, err
|
|
}
|
|
|
|
func FromDir(baseDir, ext string, fm template.FuncMap) (Map, error) {
|
|
dir := filepath.Dir(baseDir)
|
|
root := filepath.Base(baseDir)
|
|
return FromFS(os.DirFS(dir), root, ext, fm)
|
|
}
|