zk/adapter/handlebars/handlebars.go

83 lines
2.1 KiB
Go
Raw Normal View History

2020-12-26 15:53:04 +00:00
package handlebars
import (
"html"
"path/filepath"
"github.com/aymerick/raymond"
2020-12-26 19:10:39 +00:00
"github.com/mickael-menu/zk/adapter/handlebars/helpers"
2020-12-27 17:09:45 +00:00
"github.com/mickael-menu/zk/util"
"github.com/mickael-menu/zk/util/date"
2020-12-26 15:53:04 +00:00
"github.com/mickael-menu/zk/util/errors"
)
2020-12-27 17:09:45 +00:00
func Init(lang string, logger util.Logger, date date.Provider) {
helpers.RegisterSlug(logger, lang)
helpers.RegisterDate(logger, date)
2020-12-27 17:58:22 +00:00
helpers.RegisterShell(logger)
2020-12-26 19:10:39 +00:00
}
2020-12-26 15:53:04 +00:00
// 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) {
res, err := raymond.Render(template, context)
if err != nil {
return "", errors.Wrap(err, "render template failed")
}
2020-12-26 19:10:39 +00:00
2020-12-26 15:53:04 +00:00
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.
2020-12-26 19:10:39 +00:00
templ, err = raymond.ParseFile(path)
2020-12-26 15:53:04 +00:00
if err != nil {
return nil, wrap(err)
}
hr.templates[path] = templ
return templ, nil
}