Source file src/pkg/text/template/template.go
1
2
3
4
5 package template
6
7 import (
8 "fmt"
9 "reflect"
10 "text/template/parse"
11 )
12
13
14 type common struct {
15 tmpl map[string]*Template
16
17
18
19 parseFuncs FuncMap
20 execFuncs map[string]reflect.Value
21 }
22
23
24
25
26 type Template struct {
27 name string
28 *parse.Tree
29 *common
30 leftDelim string
31 rightDelim string
32 }
33
34
35 func New(name string) *Template {
36 return &Template{
37 name: name,
38 }
39 }
40
41
42 func (t *Template) Name() string {
43 return t.name
44 }
45
46
47
48
49 func (t *Template) New(name string) *Template {
50 t.init()
51 return &Template{
52 name: name,
53 common: t.common,
54 leftDelim: t.leftDelim,
55 rightDelim: t.rightDelim,
56 }
57 }
58
59 func (t *Template) init() {
60 if t.common == nil {
61 t.common = new(common)
62 t.tmpl = make(map[string]*Template)
63 t.parseFuncs = make(FuncMap)
64 t.execFuncs = make(map[string]reflect.Value)
65 }
66 }
67
68
69
70
71
72
73
74 func (t *Template) Clone() (*Template, error) {
75 nt := t.copy(nil)
76 nt.init()
77 nt.tmpl[t.name] = nt
78 for k, v := range t.tmpl {
79 if k == t.name {
80 continue
81 }
82
83 tmpl := v.copy(nt.common)
84 nt.tmpl[k] = tmpl
85 }
86 for k, v := range t.parseFuncs {
87 nt.parseFuncs[k] = v
88 }
89 for k, v := range t.execFuncs {
90 nt.execFuncs[k] = v
91 }
92 return nt, nil
93 }
94
95
96 func (t *Template) copy(c *common) *Template {
97 nt := New(t.name)
98 nt.Tree = t.Tree
99 nt.common = c
100 nt.leftDelim = t.leftDelim
101 nt.rightDelim = t.rightDelim
102 return nt
103 }
104
105
106
107 func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error) {
108 if t.tmpl[name] != nil {
109 return nil, fmt.Errorf("template: redefinition of template %q", name)
110 }
111 nt := t.New(name)
112 nt.Tree = tree
113 t.tmpl[name] = nt
114 return nt, nil
115 }
116
117
118
119 func (t *Template) Templates() []*Template {
120 if t.common == nil {
121 return nil
122 }
123
124 m := make([]*Template, 0, len(t.tmpl))
125 for _, v := range t.tmpl {
126 m = append(m, v)
127 }
128 return m
129 }
130
131
132
133
134
135
136 func (t *Template) Delims(left, right string) *Template {
137 t.leftDelim = left
138 t.rightDelim = right
139 return t
140 }
141
142
143
144
145
146 func (t *Template) Funcs(funcMap FuncMap) *Template {
147 t.init()
148 addValueFuncs(t.execFuncs, funcMap)
149 addFuncs(t.parseFuncs, funcMap)
150 return t
151 }
152
153
154
155 func (t *Template) Lookup(name string) *Template {
156 if t.common == nil {
157 return nil
158 }
159 return t.tmpl[name]
160 }
161
162
163
164
165
166
167
168
169 func (t *Template) Parse(text string) (*Template, error) {
170 t.init()
171 trees, err := parse.Parse(t.name, text, t.leftDelim, t.rightDelim, t.parseFuncs, builtins)
172 if err != nil {
173 return nil, err
174 }
175
176 for name, tree := range trees {
177
178
179 tmpl := t
180 if name != t.name {
181 tmpl = t.New(name)
182 }
183
184 if replace, err := t.associate(tmpl, tree); err != nil {
185 return nil, err
186 } else if replace {
187 tmpl.Tree = tree
188 }
189 tmpl.leftDelim = t.leftDelim
190 tmpl.rightDelim = t.rightDelim
191 }
192 return t, nil
193 }
194
195
196
197
198
199 func (t *Template) associate(new *Template, tree *parse.Tree) (bool, error) {
200 if new.common != t.common {
201 panic("internal error: associate not common")
202 }
203 name := new.name
204 if old := t.tmpl[name]; old != nil {
205 oldIsEmpty := parse.IsEmptyTree(old.Root)
206 newIsEmpty := parse.IsEmptyTree(tree.Root)
207 if newIsEmpty {
208
209 return false, nil
210 }
211 if !oldIsEmpty {
212 return false, fmt.Errorf("template: redefinition of template %q", name)
213 }
214 }
215 t.tmpl[name] = new
216 return true, nil
217 }
View as plain text