File: template.go

package info (click to toggle)
incus 6.0.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 24,392 kB
  • sloc: sh: 16,313; ansic: 3,121; python: 457; makefile: 337; ruby: 51; sql: 50; lisp: 6
file content (49 lines) | stat: -rw-r--r-- 1,207 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package util

import (
	"errors"
	"fmt"
	"strings"

	"github.com/flosch/pongo2"
)

// RenderTemplate renders a pongo2 template with nesting support.
// This supports up to 3 levels of nesting (to avoid loops).
func RenderTemplate(template string, ctx pongo2.Context) (string, error) {
	// Prepare a custom set.
	custom := pongo2.NewSet("render-template", pongo2.DefaultLoader)

	// Block the use of some tags.
	for _, tag := range []string{"extends", "import", "include", "ssi"} {
		err := custom.BanTag(tag)
		if err != nil {
			return "", fmt.Errorf("Failed to configure custom pongo2 parser: Failed to block tag tag %q: %w", tag, err)
		}
	}

	// Limit recursion to 3 levels.
	for range 3 {
		// Load template from string
		tpl, err := custom.FromString("{% autoescape off %}" + template + "{% endautoescape %}")
		if err != nil {
			return "", err
		}

		// Get rendered template
		ret, err := tpl.Execute(ctx)
		if err != nil {
			return ret, err
		}

		// Check if another pass is needed.
		if !strings.Contains(ret, "{{") && !strings.Contains(ret, "{%") {
			return ret, nil
		}

		// Prepare for another run.
		template = ret
	}

	return "", errors.New("Maximum template recursion limit reached")
}