mirror of
https://github.com/mickael-menu/zk
synced 2024-11-17 09:25:44 +00:00
79 lines
1.9 KiB
Go
79 lines
1.9 KiB
Go
|
package handlebars
|
||
|
|
||
|
import (
|
||
|
"html"
|
||
|
"io/ioutil"
|
||
|
"path/filepath"
|
||
|
|
||
|
"github.com/aymerick/raymond"
|
||
|
"github.com/mickael-menu/zk/util/errors"
|
||
|
)
|
||
|
|
||
|
// HandlebarsRenderer holds parsed handlebars template and renders them.
|
||
|
type HandlebarsRenderer struct {
|
||
|
templates map[string]*raymond.Template
|
||
|
}
|
||
|
|
||
|
// NewRenderer creates a new instance of HandlebarsRenderer.
|
||
|
func NewRenderer() *HandlebarsRenderer {
|
||
|
return &HandlebarsRenderer{
|
||
|
templates: make(map[string]*raymond.Template),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Render renders a handlebars string template with the given context.
|
||
|
func (hr *HandlebarsRenderer) Render(template string, context interface{}) (string, error) {
|
||
|
template = html.EscapeString(template)
|
||
|
res, err := raymond.Render(template, context)
|
||
|
if err != nil {
|
||
|
return "", errors.Wrap(err, "render template failed")
|
||
|
}
|
||
|
return html.UnescapeString(res), nil
|
||
|
}
|
||
|
|
||
|
// RenderFile renders a handlebars template file with the given context.
|
||
|
func (hr *HandlebarsRenderer) RenderFile(path string, context interface{}) (string, error) {
|
||
|
wrap := errors.Wrapper("render template failed")
|
||
|
|
||
|
templ, err := hr.loadFileTemplate(path)
|
||
|
if err != nil {
|
||
|
return "", wrap(err)
|
||
|
}
|
||
|
|
||
|
res, err := templ.Exec(context)
|
||
|
if err != nil {
|
||
|
return "", wrap(err)
|
||
|
}
|
||
|
|
||
|
return html.UnescapeString(res), nil
|
||
|
}
|
||
|
|
||
|
// LoadFileTemplate loads the template at given path into the renderer if needed.
|
||
|
// Returns the parsed template.
|
||
|
func (hr *HandlebarsRenderer) loadFileTemplate(path string) (*raymond.Template, error) {
|
||
|
wrap := errors.Wrapperf("load template file failed: %v", path)
|
||
|
|
||
|
path, err := filepath.Abs(path)
|
||
|
if err != nil {
|
||
|
return nil, wrap(err)
|
||
|
}
|
||
|
|
||
|
// Already loaded?
|
||
|
templ, ok := hr.templates[path]
|
||
|
if ok {
|
||
|
return templ, nil
|
||
|
}
|
||
|
|
||
|
// Load new template.
|
||
|
bytes, err := ioutil.ReadFile(path)
|
||
|
if err != nil {
|
||
|
return nil, wrap(err)
|
||
|
}
|
||
|
templ, err = raymond.Parse(html.EscapeString(string(bytes)))
|
||
|
if err != nil {
|
||
|
return nil, wrap(err)
|
||
|
}
|
||
|
hr.templates[path] = templ
|
||
|
return templ, nil
|
||
|
}
|