OLD | NEW |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package template | 5 package template |
6 | 6 |
7 import ( | 7 import ( |
8 "exp/template/parse" | 8 "exp/template/parse" |
9 "os" | 9 "os" |
10 "reflect" | 10 "reflect" |
11 ) | 11 ) |
12 | 12 |
13 // Template is the representation of a parsed template. | 13 // Template is the representation of a parsed template. |
14 type Template struct { | 14 type Template struct { |
15 name string | 15 name string |
16 *parse.Tree | 16 *parse.Tree |
17 » funcs map[string]reflect.Value | 17 » // We use two maps, one for parsing and one for execution. |
18 » set *Set // can be nil. | 18 » // This separation makes the API cleaner since it doesn't |
| 19 » // expose reflection to the client. |
| 20 » parseFuncs FuncMap |
| 21 » execFuncs map[string]reflect.Value |
| 22 » set *Set // can be nil. |
19 } | 23 } |
20 | 24 |
21 // Name returns the name of the template. | 25 // Name returns the name of the template. |
22 func (t *Template) Name() string { | 26 func (t *Template) Name() string { |
23 return t.Tree.Name | 27 return t.Tree.Name |
24 } | 28 } |
25 | 29 |
26 // Parsing. | 30 // Parsing. |
27 | 31 |
28 // New allocates a new template with the given name. | 32 // New allocates a new template with the given name. |
29 func New(name string) *Template { | 33 func New(name string) *Template { |
30 return &Template{ | 34 return &Template{ |
31 » » name: name, | 35 » » name: name, |
32 » » funcs: make(map[string]reflect.Value), | 36 » » parseFuncs: make(FuncMap), |
| 37 » » execFuncs: make(map[string]reflect.Value), |
33 } | 38 } |
34 } | 39 } |
35 | 40 |
36 // Funcs adds the elements of the argument map to the template's function | 41 // Funcs adds the elements of the argument map to the template's function |
37 // map. It panics if a value in the map is not a function with appropriate | 42 // map. It panics if a value in the map is not a function with appropriate |
38 // return type. | 43 // return type. |
39 // The return value is the template, so calls can be chained. | 44 // The return value is the template, so calls can be chained. |
40 func (t *Template) Funcs(funcMap FuncMap) *Template { | 45 func (t *Template) Funcs(funcMap FuncMap) *Template { |
41 » addFuncs(t.funcs, funcMap) | 46 » addValueFuncs(t.execFuncs, funcMap) |
| 47 » addFuncs(t.parseFuncs, funcMap) |
42 return t | 48 return t |
43 } | 49 } |
44 | 50 |
45 // Parse parses the template definition string to construct an internal | 51 // Parse parses the template definition string to construct an internal |
46 // representation of the template for execution. | 52 // representation of the template for execution. |
47 func (t *Template) Parse(s string) (tmpl *Template, err os.Error) { | 53 func (t *Template) Parse(s string) (tmpl *Template, err os.Error) { |
48 » t.Tree, err = parse.New(t.name).Parse(s, t.funcs, builtins) | 54 » t.Tree, err = parse.New(t.name).Parse(s, t.parseFuncs, builtins) |
49 if err != nil { | 55 if err != nil { |
50 return nil, err | 56 return nil, err |
51 } | 57 } |
52 return t, nil | 58 return t, nil |
53 } | 59 } |
54 | 60 |
55 // ParseInSet parses the template definition string to construct an internal | 61 // ParseInSet parses the template definition string to construct an internal |
56 // representation of the template for execution. It also adds the template | 62 // representation of the template for execution. It also adds the template |
57 // to the set. | 63 // to the set. |
58 // Function bindings are checked against those in the set. | 64 // Function bindings are checked against those in the set. |
59 func (t *Template) ParseInSet(s string, set *Set) (tmpl *Template, err os.Error)
{ | 65 func (t *Template) ParseInSet(s string, set *Set) (tmpl *Template, err os.Error)
{ |
60 » var setFuncs map[string]reflect.Value | 66 » var setFuncs FuncMap |
61 if set != nil { | 67 if set != nil { |
62 » » setFuncs = set.funcs | 68 » » setFuncs = set.parseFuncs |
63 } | 69 } |
64 » t.Tree, err = parse.New(t.name).Parse(s, t.funcs, setFuncs, builtins) | 70 » t.Tree, err = parse.New(t.name).Parse(s, t.parseFuncs, setFuncs, builtin
s) |
65 if err != nil { | 71 if err != nil { |
66 return nil, err | 72 return nil, err |
67 } | 73 } |
68 t.addToSet(set) | 74 t.addToSet(set) |
69 return t, nil | 75 return t, nil |
70 } | 76 } |
71 | 77 |
72 // addToSet adds the template to the set, verifying it's not being double-assign
ed. | 78 // addToSet adds the template to the set, verifying it's not being double-assign
ed. |
73 func (t *Template) addToSet(set *Set) { | 79 func (t *Template) addToSet(set *Set) { |
74 if set == nil || t.set == set { | 80 if set == nil || t.set == set { |
75 return | 81 return |
76 } | 82 } |
77 // If double-assigned, Add will panic and we will turn that into an erro
r. | 83 // If double-assigned, Add will panic and we will turn that into an erro
r. |
78 set.Add(t) | 84 set.Add(t) |
79 } | 85 } |
OLD | NEW |