...
1 package exec
2
3 import (
4 "bytes"
5 "io"
6 "strings"
7
8 "github.com/pkg/errors"
9
10 "github.com/noirbizarre/gonja/nodes"
11 "github.com/noirbizarre/gonja/parser"
12 "github.com/noirbizarre/gonja/tokens"
13 )
14
15 type TemplateLoader interface {
16 GetTemplate(string) (*Template, error)
17 }
18
19 type Template struct {
20 Name string
21 Reader io.Reader
22 Source string
23
24 Env *EvalConfig
25 Loader TemplateLoader
26
27 Tokens *tokens.Stream
28 Parser *parser.Parser
29
30 Root *nodes.Template
31 Macros MacroSet
32 }
33
34 func NewTemplate(name string, source string, cfg *EvalConfig) (*Template, error) {
35
36 t := &Template{
37 Env: cfg,
38 Name: name,
39 Source: source,
40 Tokens: tokens.Lex(source),
41 }
42
43
44 t.Parser = parser.NewParser(name, cfg.Config, t.Tokens)
45 t.Parser.Statements = *t.Env.Statements
46 t.Parser.TemplateParser = t.Env.GetTemplate
47 root, err := t.Parser.Parse()
48 if err != nil {
49 return nil, err
50 }
51 t.Root = root
52
53 return t, nil
54 }
55
56 func (tpl *Template) execute(ctx map[string]interface{}, out io.StringWriter) error {
57 exCtx := tpl.Env.Globals.Inherit()
58 exCtx.Update(ctx)
59
60 var builder strings.Builder
61 renderer := NewRenderer(exCtx, &builder, tpl.Env, tpl)
62
63 err := renderer.Execute()
64 if err != nil {
65 return errors.Wrap(err, `Unable to Execute template`)
66 }
67 out.WriteString(renderer.String())
68
69 return nil
70 }
71
72 func (tpl *Template) newBufferAndExecute(ctx map[string]interface{}) (*bytes.Buffer, error) {
73 var buffer bytes.Buffer
74
75
76
77 if err := tpl.execute(ctx, &buffer); err != nil {
78 return nil, err
79 }
80 return &buffer, nil
81 }
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 func (tpl *Template) ExecuteBytes(ctx map[string]interface{}) ([]byte, error) {
109 buffer, err := tpl.newBufferAndExecute(ctx)
110 if err != nil {
111 return nil, err
112 }
113 return buffer.Bytes(), nil
114 }
115
116
117 func (tpl *Template) Execute(ctx map[string]interface{}) (string, error) {
118 var b strings.Builder
119 err := tpl.execute(ctx, &b)
120 if err != nil {
121 return "", err
122 }
123
124 return b.String(), nil
125 }
126
View as plain text