diff options
| author | Rob Pike <r@golang.org> | 2011-11-23 20:17:22 -0800 |
|---|---|---|
| committer | Rob Pike <r@golang.org> | 2011-11-23 20:17:22 -0800 |
| commit | f56db6f534759b211666f2218da1d44d7abbdd54 (patch) | |
| tree | a9b9aba03287822529a5f31d93c95f0c7bd3f8f3 /src/pkg/text/template/exec.go | |
| parent | af081cd43ee3a69f89c5a00ab830111cae99d94a (diff) | |
| download | go-f56db6f534759b211666f2218da1d44d7abbdd54.tar.xz | |
text/template: new, simpler API
The Set type is gone. Instead, templates are automatically associated by
being parsed together; nested definitions implicitly create associations.
Only associated templates can invoke one another.
This approach dramatically reduces the breadth of the construction API.
For now, html/template is deleted from src/pkg/Makefile, so this can
be checked in. Nothing in the tree depends on it. It will be updated next.
R=dsymonds, adg, rsc, r, gri, mikesamuel, nigeltao
CC=golang-dev
https://golang.org/cl/5415060
Diffstat (limited to 'src/pkg/text/template/exec.go')
| -rw-r--r-- | src/pkg/text/template/exec.go | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/src/pkg/text/template/exec.go b/src/pkg/text/template/exec.go index 19108825d5..b74bc3b01c 100644 --- a/src/pkg/text/template/exec.go +++ b/src/pkg/text/template/exec.go @@ -85,8 +85,18 @@ func errRecover(errp *error) { } } +// ExecuteTemplate applies the template associated with t that has the given name +// to the specified data object and writes the output to wr. +func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error { + tmpl := t.tmpl[name] + if tmpl == nil { + return fmt.Errorf("template: no template %q associated with template %q", name, t.name) + } + return tmpl.Execute(wr, data) +} + // Execute applies a parsed template to the specified data object, -// writing the output to wr. +// and writes the output to wr. func (t *Template) Execute(wr io.Writer, data interface{}) (err error) { defer errRecover(&err) value := reflect.ValueOf(data) @@ -251,13 +261,9 @@ func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) { } func (s *state) walkTemplate(dot reflect.Value, t *parse.TemplateNode) { - set := s.tmpl.set - if set == nil { - s.errorf("no set defined in which to invoke template named %q", t.Name) - } - tmpl := set.tmpl[t.Name] + tmpl := s.tmpl.tmpl[t.Name] if tmpl == nil { - s.errorf("template %q not in set", t.Name) + s.errorf("template %q not defined", t.Name) } // Variables declared by the pipeline persist. dot = s.evalPipeline(dot, t.Pipe) @@ -376,7 +382,7 @@ func (s *state) evalFieldChain(dot, receiver reflect.Value, ident []string, args } func (s *state) evalFunction(dot reflect.Value, name string, args []parse.Node, final reflect.Value) reflect.Value { - function, ok := findFunction(name, s.tmpl, s.tmpl.set) + function, ok := findFunction(name, s.tmpl) if !ok { s.errorf("%q is not a defined function", name) } @@ -398,7 +404,7 @@ func (s *state) evalField(dot reflect.Value, fieldName string, args []parse.Node if ptr.Kind() != reflect.Interface && ptr.CanAddr() { ptr = ptr.Addr() } - if method, ok := methodByName(ptr, fieldName); ok { + if method := ptr.MethodByName(fieldName); method.IsValid() { return s.evalCall(dot, method, fieldName, args, final) } hasArgs := len(args) > 1 || final.IsValid() @@ -433,17 +439,6 @@ func (s *state) evalField(dot reflect.Value, fieldName string, args []parse.Node panic("not reached") } -// TODO: delete when reflect's own MethodByName is released. -func methodByName(receiver reflect.Value, name string) (reflect.Value, bool) { - typ := receiver.Type() - for i := 0; i < typ.NumMethod(); i++ { - if typ.Method(i).Name == name { - return receiver.Method(i), true // This value includes the receiver. - } - } - return zero, false -} - var ( errorType = reflect.TypeOf((*error)(nil)).Elem() fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() |
