@ -38,8 +38,7 @@ type Engine struct {
FuncMap template . FuncMap
// If strict is enabled, template rendering will fail if a template references
// a value that was not passed in.
Strict bool
CurrentTemplates map [ string ] renderable
Strict bool
// In LintMode, some 'required' template values may be missing, so don't fail
LintMode bool
}
@ -122,7 +121,6 @@ func FuncMap() template.FuncMap {
func ( e * Engine ) Render ( chrt * chart . Chart , values chartutil . Values ) ( map [ string ] string , error ) {
// Render the charts
tmap := allTemplates ( chrt , values )
e . CurrentTemplates = tmap
return e . render ( tmap )
}
@ -139,7 +137,7 @@ type renderable struct {
// alterFuncMap takes the Engine's FuncMap and adds context-specific functions.
//
// The resulting FuncMap is only valid for the passed-in template.
func ( e * Engine ) alterFuncMap ( t * template . Template ) template . FuncMap {
func ( e * Engine ) alterFuncMap ( t * template . Template , referenceTpls map [ string ] renderable ) template . FuncMap {
// Clone the func map because we are adding context-specific functions.
var funcMap template . FuncMap = map [ string ] interface { } { }
for k , v := range e . FuncMap {
@ -198,7 +196,7 @@ func (e *Engine) alterFuncMap(t *template.Template) template.FuncMap {
templates [ templateName . ( string ) ] = r
result , err := e . render ( template s)
result , err := e . render WithReferences ( template s, referenceTpl s)
if err != nil {
return "" , fmt . Errorf ( "Error during tpl function execution for %q: %s" , tpl , err . Error ( ) )
}
@ -210,6 +208,12 @@ func (e *Engine) alterFuncMap(t *template.Template) template.FuncMap {
// render takes a map of templates/values and renders them.
func ( e * Engine ) render ( tpls map [ string ] renderable ) ( rendered map [ string ] string , err error ) {
return e . renderWithReferences ( tpls , tpls )
}
// renderWithReferences takes a map of templates/values to render, and a map of
// templates which can be referenced within them.
func ( e * Engine ) renderWithReferences ( tpls map [ string ] renderable , referenceTpls map [ string ] renderable ) ( rendered map [ string ] string , err error ) {
// Basically, what we do here is start with an empty parent template and then
// build up a list of templates -- one for each file. Once all of the templates
// have been parsed, we loop through again and execute every template.
@ -231,7 +235,7 @@ func (e *Engine) render(tpls map[string]renderable) (rendered map[string]string,
t . Option ( "missingkey=zero" )
}
funcMap := e . alterFuncMap ( t )
funcMap := e . alterFuncMap ( t , referenceTpls )
// We want to parse the templates in a predictable order. The order favors
// higher-level (in file system) templates over deeply nested templates.
@ -248,9 +252,9 @@ func (e *Engine) render(tpls map[string]renderable) (rendered map[string]string,
files = append ( files , fname )
}
// Adding the engine's currentT emplates to the template context
// Adding the reference t emplates to the template context
// so they can be referenced in the tpl function
for fname , r := range e. CurrentTemplate s {
for fname , r := range referenceTpl s {
if t . Lookup ( fname ) == nil {
t = t . New ( fname ) . Funcs ( funcMap )
if _ , err := t . Parse ( r . tpl ) ; err != nil {