symbols := teasy.SymbolMap{
"obj": &Object{Value1: "abc"},
"add": add,
"count": count,
"dddArg": dddArg,
"die": func() bool { panic("die") },
"echo": echo,
"makemap": makemap,
"mapOfThree": mapOfThree,
"oneArg": oneArg,
"returnInt": returnInt,
"stringer": stringer,
"twoArgs": twoArgs,
"typeOf": typeOf,
"valueString": valueString,
"vfunc": vfunc,
"zeroArgs": zeroArgs,
"lower": strings.ToLower,
"upper": strings.ToUpper,
"repeat": strings.Repeat,
"replace": strings.Replace,
"replaceAll": strings.ReplaceAll,
"concat": func(a ...string) string {
sb := strings.Builder{}
for _, s := range a {
sb.WriteString(s)
}
return sb.String()
},
}
tmpl, err := teasy.New("template").Symbols(symbols).Parse(text)
if err != nil {
return "", fmt.Errorf(`error: %s while executing "%s"`, err.Error(), tmpl.Name())
}
b := new(strings.Builder)
err = tmpl.Execute(b, data)
if err != nil {
return "", err
}
return b.String(), nil
- Use parentheses as a pipeline(function, call)
text = `{{ concat(repeat("a", 3), "b") | upper}}` // AAAB
- Use the
?
as a placeholder for an input variable passed from the pipeline
text = `{{ "abc"| concat(?,?) | upper}}` // ABCABC
text = "{{ .NonEmptyInterface | print(? | ?.X) | ? }}" // x
be careful
- The support for automatically adding the pipeline variable to the call arguments has been removed.
text = `{{ "abc"| concat("cde") | upper}}` // CDE
text = `{{ "abc"| concat("cde", ?) | upper}}` // CDEABC
- The pipeline variable will be automatically appended to the call arguments only when no argument is supplied.
text = `{{ "abc"| concat | upper }}` // ABC
text = `{{ "abc"| concat ? | upper ? }}` // ABC
text = `{{ "abc"| concat(?) | upper(?) }}` // ABC
- Replace
Funcs
withSymbols
, you can use variables, functions
type Object struct {
Value1 string
}
func (o *Object) GetVal1() string {
return o.Value1
}
symbols := SymbolMap{
"obj": &Object{Value1: "abc"},
"add": add,
"count": count,
"dddArg": dddArg,
"die": func() bool { panic("die") },
"echo": echo,
"makemap": makemap,
"mapOfThree": mapOfThree,
"oneArg": oneArg,
"returnInt": returnInt,
"stringer": stringer,
"twoArgs": twoArgs,
"typeOf": typeOf,
"valueString": valueString,
"vfunc": vfunc,
"zeroArgs": zeroArgs,
"lower": strings.ToLower,
"upper": strings.ToUpper,
"repeat": strings.Repeat,
"replace": strings.Replace,
"replaceAll": strings.ReplaceAll,
"concat": func(a ...string) string {
sb := strings.Builder{}
for _, s := range a {
sb.WriteString(s)
}
return sb.String()
},
}
text = `{{ obj.GetVal1() }}` // abc
text = `{{ obj.Value1 }}` // abc
Important
, Behaviors that differ from the Go library
The following template code will panic in the Go library:
text = `{{ nil }}` // panic
But this template code won't panic in the Go library:
type T struct {
Empty0 any // nil
}
tmpl.Execute(b, &T{})
text = `{{ .Empty0 }}` // result is "<no value>"
So, I standardized them to be the same, the flow template codes are now returning <no value>
text = `{{ nil }}` // <no value>
text = `{{ .Empty0 }}` // <no value>
text = "{{(nil).True}}" // <no value>
text = "{{$x := nil}}{{$x.anything}}" // <no value>
the flow template code is now returning empty string:
text = "{{if nil}}TRUE{{end}}" // ""