Skip to content

Commit aea0de0

Browse files
committed
feat: add include template function
1 parent f232f0e commit aea0de0

File tree

4 files changed

+28
-6
lines changed

4 files changed

+28
-6
lines changed

docs/site/docs/usage.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ The rest of the files are rendered from the templates. You can edit the template
8989

9090
## Templating
9191

92-
Templates are done by using [Go templates](https://pkg.go.dev/text/template). Examples of how to write these templates can be found in [this article](https://www.digitalocean.com/community/tutorials/how-to-use-templates-in-go#step-4-writing-a-template) and in the [example recipe](https://github.com/futurice/jalapeno/blob/main/examples/variable-types/templates/README.md?plain=1).
92+
Templates are done by using [Go templates](https://pkg.go.dev/text/template) extended with [sprig functions](https://masterminds.github.io/sprig/). Examples of how to write these templates can be found in [this article](https://www.digitalocean.com/community/tutorials/how-to-use-templates-in-go#step-4-writing-a-template) and in the [example recipe](https://github.com/futurice/jalapeno/blob/main/examples/variable-types/templates/README.md?plain=1).
9393

9494
The following context is available on the templates:
9595

pkg/engine/engine.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func New() Engine {
1616

1717
func (e Engine) Render(templates map[string][]byte, values map[string]interface{}) (map[string][]byte, error) {
1818
t := template.New("gotpl")
19-
t.Funcs(funcMap())
19+
t.Funcs(funcMap(t))
2020

2121
rendered := make(map[string][]byte)
2222

pkg/engine/engine_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,14 @@ func TestRender(t *testing.T) {
3030
{
3131
"macros",
3232
map[string][]byte{
33+
"templates/main": []byte("{{ template \"helper1\" }} {{ template \"helper2\" }} {{ include \"helper3\" . | upper }}"),
3334
"templates/helper1": []byte("{{ define \"helper1\" }}ONE{{ end }}"),
34-
"templates/main": []byte("{{ template \"helper1\" }} {{ template \"helper2\" }}"),
3535
"templates/helper2": []byte("{{ define \"helper2\" }}TWO{{ end }}"),
36+
"templates/helper3": []byte("{{ define \"helper3\" }}three{{ end }}"),
3637
},
3738
map[string]interface{}{},
3839
map[string][]byte{
39-
"templates/main": []byte("ONE TWO"),
40+
"templates/main": []byte("ONE TWO THREE"),
4041
},
4142
},
4243
}

pkg/engine/funcs.go

+23-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package engine
22

33
import (
4+
"fmt"
45
"math/big"
56
"math/rand"
67
"strings"
@@ -11,10 +12,12 @@ import (
1112

1213
var prngs = make(map[string]*rand.Rand)
1314

14-
func funcMap() template.FuncMap {
15+
func funcMap(t *template.Template) template.FuncMap {
1516
f := sprig.TxtFuncMap()
17+
includedNames := make(map[string]int)
1618

17-
// Add additional template functions here
19+
// Custom template functions
20+
f["include"] = includeFun(t, includedNames)
1821
f["stableRandomAlphanumeric"] = stableRandomAlphanumeric
1922

2023
return f
@@ -23,6 +26,7 @@ func funcMap() template.FuncMap {
2326
const lowerAlpha = "abcdefghijlkmnopqrstuvwxyz"
2427
const number = "0123456789"
2528
const alphanumeric = lowerAlpha + number
29+
const recursionMaxNums = 100
2630

2731
// Generate a pseudo-random alphanumeric string of the given length
2832
// such that the sequence of strings generated by successive calls
@@ -56,3 +60,20 @@ func prngForStr(str string) *rand.Rand {
5660
func resetRngs() {
5761
prngs = make(map[string]*rand.Rand)
5862
}
63+
64+
func includeFun(t *template.Template, includedNames map[string]int) func(string, interface{}) (string, error) {
65+
return func(name string, data interface{}) (string, error) {
66+
var buf strings.Builder
67+
if v, ok := includedNames[name]; ok {
68+
if v > recursionMaxNums {
69+
return "", fmt.Errorf("unable to execute template: maximum recursion depth reached for template block \"%s\"", name)
70+
}
71+
includedNames[name]++
72+
} else {
73+
includedNames[name] = 1
74+
}
75+
err := t.ExecuteTemplate(&buf, name, data)
76+
includedNames[name]--
77+
return buf.String(), err
78+
}
79+
}

0 commit comments

Comments
 (0)