pkg/template/engine/compiler.go (57 lines of code) (raw):

// Licensed to Elasticsearch B.V. under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Elasticsearch B.V. licenses this file to you under // the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package engine import ( "bytes" "fmt" "text/template" ) // ----------------------------------------------------------------------------- // Render compile and assemble attribute template to merge with values. func Render(input string, data interface{}) (content string, err error) { // Check argument defer func() { if r := recover(); r != nil { err = fmt.Errorf("template rendering failed: %v", r) } }() // Prepare the template t, err := template.New("root"). Funcs(FuncMap(nil)). Parse(input) if err != nil { return "", fmt.Errorf("unable to compile attribute template '%s': %w", input, err) } // Fail on missing key t.Option("missingkey=error") // Merge with values var out bytes.Buffer if err := t.Execute(&out, data); err != nil { return "", fmt.Errorf("unable to merge data with template '%s': %w", input, err) } // No error return out.String(), nil } // RenderContext compile and assemble attribute template to merge with values. func RenderContext(templateContext Context, input string) (string, error) { return RenderContextWithData(templateContext, input, nil) } // RenderContextWithData compile and assemble attribute template to merge with values. func RenderContextWithData(templateContext Context, input string, data interface{}) (content string, err error) { // Check argument defer func() { if r := recover(); r != nil { err = fmt.Errorf("template rendering failed: %v", r) } }() // Retrieve delimiters leftDelim, rightDelim := templateContext.Delims() // Prepare the template t, err := template.New(templateContext.Name()). Delims(leftDelim, rightDelim). Funcs(FuncMap(templateContext.SecretReaders())). Parse(input) if err != nil { return "", fmt.Errorf("unable to compile attribute template '%s': %w", input, err) } // Check strict mode if templateContext.StrictMode() { // Fail on missing key t.Option("missingkey=error") } else { // Not that zero will attempt to add default values for types it knows, // but will still emit <no value> for others. We mitigate that later. t.Option("missingkey=zero") } // Merge with values var out bytes.Buffer if err := t.Execute(&out, map[string]interface{}{ "Data": data, "Values": templateContext.Values(), "Files": templateContext.Files(), }); err != nil { return "", fmt.Errorf("unable to merge values with template '%s': %w", input, err) } // No error return out.String(), nil }