Left: | ||
Right: |
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 // Helper functions to make constructing templates and sets easier. | 5 // Helper functions to make constructing templates easier. |
6 | 6 |
7 package template | 7 package template |
8 | 8 |
9 import ( | 9 import ( |
10 "fmt" | 10 "fmt" |
11 "io/ioutil" | 11 "io/ioutil" |
12 "path/filepath" | 12 "path/filepath" |
13 ) | 13 ) |
14 | 14 |
15 // Functions and methods to parse a single template. | 15 // Functions and methods to parse templates. |
16 | 16 |
17 // Must is a helper that wraps a call to a function returning (*Template, error) | 17 // Must is a helper that wraps a call to a function returning (*Template, error) |
18 // and panics if the error is non-nil. It is intended for use in variable initia lizations | 18 // and panics if the error is non-nil. It is intended for use in variable initia lizations |
19 // such as | 19 // such as |
20 // var t = template.Must(template.New("name").Parse("text")) | 20 // var t = template.Must(template.New("name").Parse("text")) |
21 func Must(t *Template, err error) *Template { | 21 func Must(t *Template, err error) *Template { |
22 if err != nil { | 22 if err != nil { |
23 panic(err) | 23 panic(err) |
24 } | 24 } |
25 return t | 25 return t |
26 } | 26 } |
27 | 27 |
28 // ParseFile creates a new Template and parses the template definition from | 28 // ParseFiles creates a new Template and parses the template definitions from |
29 // the named file. The template name is the base name of the file. | 29 // the named files. The returned template's name will have the (base) name and |
30 func ParseFile(filename string) (*Template, error) { | 30 // (parsed) contents of the first file. |
31 » t := New(filepath.Base(filename)) | 31 // There must be at least one file. |
32 » return t.ParseFile(filename) | 32 // If an error occurs, parsing stops and the returned *Template is nil. |
33 func ParseFiles(filenames ...string) (*Template, error) { | |
34 » return parseFiles(nil, filenames...) | |
33 } | 35 } |
34 | 36 |
35 // parseFileInSet creates a new Template and parses the template | 37 // ParseFiles parses the named files and associates the resulting templates with t. |
36 // definition from the named file. The template name is the base name | 38 // If an error occurs, parsing stops and the returned template is nil; otherwise it is t. |
37 // of the file. It also adds the template to the set. Function bindings are | 39 // There must be at least one file. |
38 // checked against those in the set. | 40 func (t *Template) ParseFiles(filenames ...string) (*Template, error) { |
39 func parseFileInSet(filename string, set *Set) (*Template, error) { | 41 » return parseFiles(t, filenames...) |
40 » t := New(filepath.Base(filename)) | |
41 » return t.parseFileInSet(filename, set) | |
42 } | 42 } |
43 | 43 |
44 // ParseFile reads the template definition from a file and parses it to | 44 // parseFiles is the helper for the method and function. If the argument |
45 // construct an internal representation of the template for execution. | 45 // template is nil, it is created from the first file. |
MikeSamuel
2011/11/23 17:04:45
Ok. Even if some glob primitives don't return fil
r
2011/11/23 17:19:19
path/filepath.Glob sorts, so it should be ok
| |
46 // The returned template will be nil if an error occurs. | 46 func parseFiles(t *Template, filenames ...string) (*Template, error) { |
47 func (t *Template) ParseFile(filename string) (*Template, error) { | 47 » if len(filenames) == 0 { |
48 » b, err := ioutil.ReadFile(filename) | 48 » » // Not really a problem, but be consistent. |
49 » if err != nil { | 49 » » return nil, fmt.Errorf("template: no files named in call to Pars eFiles") |
50 » » return nil, err | |
51 } | 50 } |
52 return t.Parse(string(b)) | |
53 } | |
54 | |
55 // parseFileInSet is the same as ParseFile except that function bindings | |
56 // are checked against those in the set and the template is added | |
57 // to the set. | |
58 // The returned template will be nil if an error occurs. | |
59 func (t *Template) parseFileInSet(filename string, set *Set) (*Template, error) { | |
60 b, err := ioutil.ReadFile(filename) | |
61 if err != nil { | |
62 return nil, err | |
63 } | |
64 return t.ParseInSet(string(b), set) | |
65 } | |
66 | |
67 // Functions and methods to parse a set. | |
68 | |
69 // SetMust is a helper that wraps a call to a function returning (*Set, error) | |
70 // and panics if the error is non-nil. It is intended for use in variable initia lizations | |
71 // such as | |
72 // var s = template.SetMust(template.ParseSetFiles("file")) | |
73 func SetMust(s *Set, err error) *Set { | |
74 if err != nil { | |
75 panic(err) | |
76 } | |
77 return s | |
78 } | |
79 | |
80 // ParseFiles parses the named files into a set of named templates. | |
81 // Each file must be parseable by itself. | |
82 // If an error occurs, parsing stops and the returned set is nil. | |
83 func (s *Set) ParseFiles(filenames ...string) (*Set, error) { | |
84 for _, filename := range filenames { | 51 for _, filename := range filenames { |
85 b, err := ioutil.ReadFile(filename) | 52 b, err := ioutil.ReadFile(filename) |
86 if err != nil { | 53 if err != nil { |
87 return nil, err | 54 return nil, err |
88 } | 55 } |
89 » » _, err = s.Parse(string(b)) | 56 » » s := string(b) |
57 » » name := filepath.Base(filename) | |
58 » » // First template becomes return value if not already defined, | |
59 » » // and we use that one for subsequent New calls to associate | |
60 » » // all the templates together. | |
61 » » if t == nil { | |
62 » » » t, err = New(name).Parse(s) | |
63 » » } else { | |
64 » » » _, err = t.New(name).Parse(s) | |
65 » » } | |
90 if err != nil { | 66 if err != nil { |
91 return nil, err | 67 return nil, err |
92 } | 68 } |
93 } | 69 } |
94 » return s, nil | 70 » return t, nil |
95 } | 71 } |
96 | 72 |
97 // ParseSetFiles creates a new Set and parses the set definition from the | 73 // ParseGlob creates a new Template and parses the template definitions from the |
98 // named files. Each file must be individually parseable. | 74 // files identified by the pattern, which must match at least one file. The |
99 func ParseSetFiles(filenames ...string) (*Set, error) { | 75 // returned template will have the (base) name and (parsed) contents of the |
100 » s := new(Set) | 76 // first file matched by the pattern. ParseGlob is equivalent to calling |
101 » for _, filename := range filenames { | 77 // ParseFiles with the list of files matched by the pattern. |
102 » » b, err := ioutil.ReadFile(filename) | 78 func ParseGlob(pattern string) (*Template, error) { |
103 » » if err != nil { | 79 » return parseGlob(nil, pattern) |
104 » » » return nil, err | |
105 » » } | |
106 » » _, err = s.Parse(string(b)) | |
107 » » if err != nil { | |
108 » » » return nil, err | |
109 » » } | |
110 » } | |
111 » return s, nil | |
112 } | 80 } |
113 | 81 |
114 // ParseGlob parses the set definition from the files identified by the | 82 // ParseGlob parses the template definitions in the files identified by the |
115 // pattern. The pattern is processed by filepath.Glob and must match at | 83 // pattern and associates the resulting templates with t. The pattern is |
116 // least one file. | 84 // processed by filepath.Glob and must match at least one file. ParseGlob is |
117 // If an error occurs, parsing stops and the returned set is nil. | 85 // equivalent to calling t.ParseFiles with the list of files matched by the |
118 func (s *Set) ParseGlob(pattern string) (*Set, error) { | 86 // pattern. |
87 func (t *Template) ParseGlob(pattern string) (*Template, error) { | |
88 » return parseGlob(t, pattern) | |
89 } | |
90 | |
91 // parseGlob is the implementation of the function and method ParseGlob. | |
92 func parseGlob(t *Template, pattern string) (*Template, error) { | |
119 filenames, err := filepath.Glob(pattern) | 93 filenames, err := filepath.Glob(pattern) |
120 if err != nil { | 94 if err != nil { |
121 return nil, err | 95 return nil, err |
122 } | 96 } |
123 if len(filenames) == 0 { | 97 if len(filenames) == 0 { |
124 » » return nil, fmt.Errorf("pattern matches no files: %#q", pattern) | 98 » » return nil, fmt.Errorf("template: pattern matches no files: %#q" , pattern) |
125 } | 99 } |
126 » return s.ParseFiles(filenames...) | 100 » return parseFiles(t, filenames...) |
127 } | 101 } |
128 | |
129 // ParseSetGlob creates a new Set and parses the set definition from the | |
130 // files identified by the pattern. The pattern is processed by filepath.Glob | |
131 // and must match at least one file. | |
132 func ParseSetGlob(pattern string) (*Set, error) { | |
133 set, err := new(Set).ParseGlob(pattern) | |
134 if err != nil { | |
135 return nil, err | |
136 } | |
137 return set, nil | |
138 } | |
139 | |
140 // Functions and methods to parse stand-alone template files into a set. | |
141 | |
142 // ParseTemplateFiles parses the named template files and adds | |
143 // them to the set. Each template will be named the base name of | |
144 // its file. | |
145 // Unlike with ParseFiles, each file should be a stand-alone template | |
146 // definition suitable for Template.Parse (not Set.Parse); that is, the | |
147 // file does not contain {{define}} clauses. ParseTemplateFiles is | |
148 // therefore equivalent to calling the ParseFile function to create | |
149 // individual templates, which are then added to the set. | |
150 // Each file must be parseable by itself. | |
151 // If an error occurs, parsing stops and the returned set is nil. | |
152 func (s *Set) ParseTemplateFiles(filenames ...string) (*Set, error) { | |
153 for _, filename := range filenames { | |
154 _, err := parseFileInSet(filename, s) | |
155 if err != nil { | |
156 return nil, err | |
157 } | |
158 } | |
159 return s, nil | |
160 } | |
161 | |
162 // ParseTemplateGlob parses the template files matched by the | |
163 // patern and adds them to the set. Each template will be named | |
164 // the base name of its file. | |
165 // Unlike with ParseGlob, each file should be a stand-alone template | |
166 // definition suitable for Template.Parse (not Set.Parse); that is, the | |
167 // file does not contain {{define}} clauses. ParseTemplateGlob is | |
168 // therefore equivalent to calling the ParseFile function to create | |
169 // individual templates, which are then added to the set. | |
170 // Each file must be parseable by itself. | |
171 // If an error occurs, parsing stops and the returned set is nil. | |
172 func (s *Set) ParseTemplateGlob(pattern string) (*Set, error) { | |
173 filenames, err := filepath.Glob(pattern) | |
174 if err != nil { | |
175 return nil, err | |
176 } | |
177 for _, filename := range filenames { | |
178 _, err := parseFileInSet(filename, s) | |
179 if err != nil { | |
180 return nil, err | |
181 } | |
182 } | |
183 return s, nil | |
184 } | |
185 | |
186 // ParseTemplateFiles creates a set by parsing the named files, | |
187 // each of which defines a single template. Each template will be | |
188 // named the base name of its file. | |
189 // Unlike with ParseFiles, each file should be a stand-alone template | |
190 // definition suitable for Template.Parse (not Set.Parse); that is, the | |
191 // file does not contain {{define}} clauses. ParseTemplateFiles is | |
192 // therefore equivalent to calling the ParseFile function to create | |
193 // individual templates, which are then added to the set. | |
194 // Each file must be parseable by itself. Parsing stops if an error is | |
195 // encountered. | |
196 func ParseTemplateFiles(filenames ...string) (*Set, error) { | |
197 set := new(Set) | |
198 set.init() | |
199 for _, filename := range filenames { | |
200 t, err := ParseFile(filename) | |
201 if err != nil { | |
202 return nil, err | |
203 } | |
204 if err := set.add(t); err != nil { | |
205 return nil, err | |
206 } | |
207 } | |
208 return set, nil | |
209 } | |
210 | |
211 // ParseTemplateGlob creates a set by parsing the files matched | |
212 // by the pattern, each of which defines a single template. The pattern | |
213 // is processed by filepath.Glob and must match at least one file. Each | |
214 // template will be named the base name of its file. | |
215 // Unlike with ParseGlob, each file should be a stand-alone template | |
216 // definition suitable for Template.Parse (not Set.Parse); that is, the | |
217 // file does not contain {{define}} clauses. ParseTemplateGlob is | |
218 // therefore equivalent to calling the ParseFile function to create | |
219 // individual templates, which are then added to the set. | |
220 // Each file must be parseable by itself. Parsing stops if an error is | |
221 // encountered. | |
222 func ParseTemplateGlob(pattern string) (*Set, error) { | |
223 set := new(Set) | |
224 filenames, err := filepath.Glob(pattern) | |
225 if err != nil { | |
226 return nil, err | |
227 } | |
228 if len(filenames) == 0 { | |
229 return nil, fmt.Errorf("pattern matches no files: %#q", pattern) | |
230 } | |
231 for _, filename := range filenames { | |
232 t, err := ParseFile(filename) | |
233 if err != nil { | |
234 return nil, err | |
235 } | |
236 if err := set.add(t); err != nil { | |
237 return nil, err | |
238 } | |
239 } | |
240 return set, nil | |
241 } | |
OLD | NEW |