Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(990)

Side by Side Diff: src/pkg/text/template/helper.go

Issue 5415060: code review 5415060: text/template: new, simpler API (Closed)
Patch Set: diff -r fd80a4497037 https://go.googlecode.com/hg/ Created 13 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
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 }
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b