forked from bitnami/render-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
handlebars_renderer.go
81 lines (67 loc) · 1.85 KB
/
handlebars_renderer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package main
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"github.com/aymerick/raymond"
)
func orHelper(a interface{}, b interface{}, options *raymond.Options) interface{} {
aStr := raymond.Str(a)
bStr := raymond.Str(b)
if aStr != "" {
return aStr
} else if bStr != "" {
return bStr
}
return ""
}
func quoteHelper(s string) raymond.SafeString {
return raymond.SafeString(fmt.Sprintf("%q", s))
}
func jsonEscapeHelper(s string) raymond.SafeString {
b, err := json.Marshal(s)
// raymond does not allow returning errors from helpers
// TODO: Setup recovering from the panic when calling Exec
if err != nil {
panic(err)
}
return raymond.SafeString(b)
}
func init() {
raymond.RegisterHelper("or", orHelper)
raymond.RegisterHelper("quote", quoteHelper)
raymond.RegisterHelper("json_escape", jsonEscapeHelper)
}
type renderer interface {
RenderTemplate(in io.Reader, data *templateData) (string, error)
}
type handlerbarsRenderer struct {
}
func newHandlerbarsRenderer() renderer {
return &handlerbarsRenderer{}
}
func (h *handlerbarsRenderer) RenderTemplate(in io.Reader, data *templateData) (string, error) {
tpl, err := h.parseTemplate(in)
if err != nil {
return "", fmt.Errorf("cannot parse template: %v", err)
}
parsedData := h.convertTemplateData(data)
return tpl.Exec(parsedData)
}
func (h *handlerbarsRenderer) parseTemplate(in io.Reader) (*raymond.Template, error) {
b, err := ioutil.ReadAll(in)
if err != nil {
return nil, err
}
return raymond.Parse(string(b))
}
// strings chars are escaped as they are considerd unsafe for HTML. We need to mark them as safe
func (h *handlerbarsRenderer) convertTemplateData(data *templateData) map[string]raymond.SafeString {
rawData := data.Data()
res := make(map[string]raymond.SafeString, len(rawData))
for key, value := range rawData {
res[key] = raymond.SafeString(value)
}
return res
}