mg-transport-core/core/template.go

80 lines
2.1 KiB
Go
Raw Normal View History

2019-09-04 15:22:27 +03:00
package core
import (
"html/template"
"github.com/gin-contrib/multitemplate"
2019-09-18 10:28:55 +03:00
"github.com/gobuffalo/packr/v2"
2019-09-04 15:22:27 +03:00
)
// Renderer wraps multitemplate.Renderer in order to make it easier to use
type Renderer struct {
multitemplate.Renderer
2019-09-18 10:28:55 +03:00
TemplatesBox *packr.Box
FuncMap template.FuncMap
alreadyAdded map[string]*template.Template
2019-09-04 15:22:27 +03:00
}
// NewRenderer is a Renderer constructor
func NewRenderer(funcMap template.FuncMap) Renderer {
return Renderer{
Renderer: multitemplate.NewRenderer(),
FuncMap: funcMap,
alreadyAdded: map[string]*template.Template{},
2019-09-04 15:22:27 +03:00
}
}
// Push is an AddFromFilesFuncs wrapper
func (r *Renderer) Push(name string, files ...string) *template.Template {
if tpl := r.getTemplate(name); tpl != nil {
return tpl
}
2019-09-18 10:28:55 +03:00
if r.TemplatesBox == nil {
return r.storeTemplate(name, r.AddFromFilesFuncs(name, r.FuncMap, files...))
2019-09-18 10:28:55 +03:00
} else {
return r.storeTemplate(name, r.addFromBox(name, r.FuncMap, files...))
2019-09-18 10:28:55 +03:00
}
2019-09-04 15:22:27 +03:00
}
2019-09-18 10:28:55 +03:00
// addFromBox adds embedded template
func (r *Renderer) addFromBox(name string, funcMap template.FuncMap, files ...string) *template.Template {
var filesData []string
for _, file := range files {
if data, err := r.TemplatesBox.FindString(file); err == nil {
filesData = append(filesData, data)
}
}
return r.AddFromStringsFuncs(name, funcMap, filesData...)
}
// storeTemplate stores built template if multitemplate.DynamicRender is used.
// Dynamic render doesn't store templates - it stores builders, that's why we can't just extract them.
// It possibly can cause data inconsistency in developer enviroments where return value from Renderer.Push is used.
func (r *Renderer) storeTemplate(name string, tpl *template.Template) *template.Template {
if _, ok := r.Renderer.(multitemplate.DynamicRender); ok {
r.alreadyAdded[name] = tpl
}
return tpl
}
// getTemplate returns template from render or from storage
func (r *Renderer) getTemplate(name string) *template.Template {
if renderer, ok := r.Renderer.(multitemplate.Render); ok {
if i, ok := renderer[name]; ok {
return i
}
}
if _, ok := r.Renderer.(multitemplate.DynamicRender); ok {
if i, ok := r.alreadyAdded[name]; ok {
return i
}
}
return nil
}