~netlandish/gobwebs

1b3151e8f36a1e3ecbebded0348eaaf6f3c0bcbd — Peter Sanchez 2 months ago 2b1c11c
Adding ability to override template variables and disable collision protection all together
2 files changed, 37 insertions(+), 3 deletions(-)

M server/server.go
M validate/template.go
M server/server.go => server/server.go +13 -0
@@ 457,6 457,19 @@ func (s *Server) AddStaticFunc(fs ...validate.StaticFunc) {
	}
}

// TemplateAllowOverride adds template map keys values that can be overridden by
// handlers. For instance, if a static func sets a template Map value of "seoData",
// your handlers can override that value if set to be allowed.
func (s *Server) TemplateAllowOverride(keys ...string) {
	s.e.Renderer.(*validate.Template).AddOverride(keys...)
}

// TemplateProtectVariables will set whether or not to protect variable name collisions
// from handler Map data.
func (s *Server) TemplateProtectVariables(protect bool) {
	s.e.Renderer.(*validate.Template).ProtectVariables(protect)
}

// addDefaultTemplateData will set the default functions and static vars in
// the template renderer
func (s *Server) addDefaultTemplateData() {

M validate/template.go => validate/template.go +24 -3
@@ 8,6 8,7 @@ import (

	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
	"golang.org/x/exp/slices"
	"netlandish.com/x/gobwebs"
)



@@ 26,7 27,10 @@ type (

		staticMap   Map
		staticFuncs []func(c echo.Context) Map
		cloned      bool

		cloned  bool
		protect bool
		allowed []string
	}
)



@@ 36,6 40,8 @@ func NewTemplate() *Template {
		templateBase: template.New(""),
		templates:    template.New(""),
		staticMap:    make(Map),
		protect:      true,
		allowed:      []string{},
	}
}



@@ 93,8 99,11 @@ func (t *Template) tmplPayload(c echo.Context, data Map) (Map, error) {
	}
	if data != nil {
		for k, v := range data {
			if _, ok := input[k]; ok {
				return nil, fmt.Errorf("Template context conflict (handler data). Reserved key: %v", k)
			if t.protect && !slices.Contains(t.allowed, k) {
				if _, ok := input[k]; ok {
					return nil, fmt.Errorf(
						"Template context conflict (handler data). Reserved key: %v", k)
				}
			}
			input[k] = v
		}


@@ 127,6 136,18 @@ func (t *Template) RenderTemplate(
	return t.render(tmpl, w, name, data, c)
}

// AddOverride will add an override value to the allowed slice
func (t *Template) AddOverride(keys ...string) {
	t.allowed = append(t.allowed, keys...)
}

// ProtectVariables will set the `protect` value. If false, when adding
// to the template values Map we will not check for name collisions from
// handler provided maps.
func (t *Template) ProtectVariables(protect bool) {
	t.protect = protect
}

// LoadTemplates parses templates given the glob pattern path
func (t *Template) LoadTemplates(path string, tfs fs.FS) error {
	var (