summaryrefslogtreecommitdiff
path: root/libgo/go/text/template
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/text/template')
-rw-r--r--libgo/go/text/template/doc.go24
-rw-r--r--libgo/go/text/template/exec.go10
-rw-r--r--libgo/go/text/template/exec_test.go8
-rw-r--r--libgo/go/text/template/multi_test.go2
-rw-r--r--libgo/go/text/template/parse/parse.go6
-rw-r--r--libgo/go/text/template/template.go8
6 files changed, 47 insertions, 11 deletions
diff --git a/libgo/go/text/template/doc.go b/libgo/go/text/template/doc.go
index 35c4c681183..ae91f4a5419 100644
--- a/libgo/go/text/template/doc.go
+++ b/libgo/go/text/template/doc.go
@@ -22,6 +22,20 @@ Actions may not span newlines, although comments can.
Once constructed, a template may be executed safely in parallel.
+Here is a trivial example that prints "17 items are made of wool".
+
+ type Inventory struct {
+ Material string
+ Count uint
+ }
+ sweaters := Inventory{"wool", 17}
+ tmpl, err := template.New("test").Parse("{{.Count}} items are made of {{.Material}}")
+ if err != nil { panic(err) }
+ err = tmpl.Execute(os.Stdout, sweaters)
+ if err != nil { panic(err) }
+
+More intricate examples appear below.
+
Actions
Here is the list of actions. "Arguments" and "pipelines" are evaluations of
@@ -128,6 +142,11 @@ An argument is a simple value, denoted by one of the following.
.Field1.Key1.Method1.Field2.Key2.Method2
Methods can also be evaluated on variables, including chaining:
$x.Method1.Field
+ - The name of a niladic function-valued struct field of the data,
+ preceded by a period, such as
+ .Function
+ Function-valued fields behave like methods (of structs) but do not
+ pass a receiver.
- The name of a niladic function, such as
fun
The result is the value of invoking the function, fun(). The return
@@ -148,6 +167,9 @@ value (argument) or a function or method call, possibly with multiple arguments:
The result is the value of calling the method with the
arguments:
dot.Method(Argument1, etc.)
+ .Function [Argument...]
+ A function-valued field of a struct works like a method but does
+ not pass the receiver.
functionName [Argument...]
The result is the value of calling the function associated
with the name:
@@ -303,7 +325,7 @@ produce the text
By construction, a template may reside in only one association. If it's
necessary to have a template addressable from multiple associations, the
template definition must be parsed multiple times to create distinct *Template
-values.
+values, or must be copied with the Clone or AddParseTree method.
Parse may be called multiple times to assemble the various associated templates;
see the ParseFiles and ParseGlob functions and methods for simple ways to parse
diff --git a/libgo/go/text/template/exec.go b/libgo/go/text/template/exec.go
index 973189a8a62..af745286c0b 100644
--- a/libgo/go/text/template/exec.go
+++ b/libgo/go/text/template/exec.go
@@ -419,10 +419,14 @@ func (s *state) evalField(dot reflect.Value, fieldName string, args []parse.Node
tField, ok := receiver.Type().FieldByName(fieldName)
if ok {
field := receiver.FieldByIndex(tField.Index)
- if hasArgs {
- s.errorf("%s is not a method but has arguments", fieldName)
- }
if tField.PkgPath == "" { // field is exported
+ // If it's a function, we must call it.
+ if field.Type().Kind() == reflect.Func {
+ return s.evalCall(dot, field, fieldName, args, final)
+ }
+ if hasArgs {
+ s.errorf("%s is not a method or function but has arguments", fieldName)
+ }
return field
}
}
diff --git a/libgo/go/text/template/exec_test.go b/libgo/go/text/template/exec_test.go
index 9bb55e48aac..159cf5100d9 100644
--- a/libgo/go/text/template/exec_test.go
+++ b/libgo/go/text/template/exec_test.go
@@ -59,6 +59,8 @@ type T struct {
PI *int
PSI *[]int
NIL *int
+ // Function (not method)
+ Func func(...string) string
// Template to test evaluation of templates.
Tmpl *Template
}
@@ -118,6 +120,7 @@ var tVal = &T{
Err: errors.New("erroozle"),
PI: newInt(23),
PSI: newIntSlice(21, 22, 23),
+ Func: func(s ...string) string { return fmt.Sprint("<", strings.Join(s, "+"), ">") },
Tmpl: Must(New("x").Parse("test template")), // "x" is the value of .X
}
@@ -297,8 +300,13 @@ var execTests = []execTest{
"{{with $x := .}}{{with .SI}}{{$.GetU.TrueFalse $.True}}{{end}}{{end}}",
"true", tVal, true},
+ // Function call
+ {".Func", "-{{.Func}}-", "-<>-", tVal, true},
+ {".Func2", "-{{.Func `he` `llo`}}-", "-<he+llo>-", tVal, true},
+
// Pipelines.
{"pipeline", "-{{.Method0 | .Method2 .U16}}-", "-Method2: 16 M0-", tVal, true},
+ {"pipeline func", "-{{.Func `llo` | .Func `he` }}-", "-<he+<llo>>-", tVal, true},
// If.
{"if true", "{{if true}}TRUE{{end}}", "TRUE", tVal, true},
diff --git a/libgo/go/text/template/multi_test.go b/libgo/go/text/template/multi_test.go
index 274f5ef1477..f205e6be1b4 100644
--- a/libgo/go/text/template/multi_test.go
+++ b/libgo/go/text/template/multi_test.go
@@ -193,7 +193,7 @@ func TestClone(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- clone := root.Clone()
+ clone := Must(root.Clone())
// Add variants to both.
_, err = root.Parse(cloneText3)
if err != nil {
diff --git a/libgo/go/text/template/parse/parse.go b/libgo/go/text/template/parse/parse.go
index 4da756657d5..35194f7dfdb 100644
--- a/libgo/go/text/template/parse/parse.go
+++ b/libgo/go/text/template/parse/parse.go
@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Package parse builds parse trees for templates. The grammar is defined
-// in the documents for the template package.
+// Package parse builds parse trees for templates as defined by text/template
+// and html/template. Clients should use those packages to construct templates
+// rather than this one, which provides shared internal data structures not
+// intended for general use.
package parse
import (
diff --git a/libgo/go/text/template/template.go b/libgo/go/text/template/template.go
index 87e39d3af74..7494f9d8c45 100644
--- a/libgo/go/text/template/template.go
+++ b/libgo/go/text/template/template.go
@@ -69,9 +69,9 @@ func (t *Template) init() {
// templates. The actual representation is not copied, but the name space of
// associated templates is, so further calls to Parse in the copy will add
// templates to the copy but not to the original. Clone can be used to prepare
-// common templates and use them with variant definitions for other templates by
-// adding the variants after the clone is made.
-func (t *Template) Clone() *Template {
+// common templates and use them with variant definitions for other templates
+// by adding the variants after the clone is made.
+func (t *Template) Clone() (*Template, error) {
nt := t.copy(nil)
nt.init()
nt.tmpl[t.name] = nt
@@ -89,7 +89,7 @@ func (t *Template) Clone() *Template {
for k, v := range t.execFuncs {
nt.execFuncs[k] = v
}
- return nt
+ return nt, nil
}
// copy returns a shallow copy of t, with common set to the argument.