问题
I am using go templates to create yaml definitions for kubernetes. I am trying to nest templates but run into issues where I can't re-use a definition simply because the indention is wrong when included. I.e., in one case the contents need indentation but do not in another. How can I control the indention of included content?
Example below. I am reusing pod.tmpl, in the first case it can be included as is. In the second case I need to indent the entire contents so it becomes member of service
{{ if (eq .Case "pod")
# NO indenting
{{ template "pod" }}
{{ end }}
{{ if (eq .Case "service")
service:
# need to indent! so contents become members of service:
{{ template "pod" }}
{{ end }}
回答1:
You should be able to pipe the output of your template to the indent
function available in the sprig package:
{{ if (eq .Case "service")
service:
# need to indent! so contents become members of service:
{{ template "pod" | indent 4 }}
{{ end }}
回答2:
I found I can work around the issue if I indent the contents of pod.tmpl and then indent the top portion to align as below
{{ if (eq $template "pod.tmpl") }}
apiVersion: v1
kind: Pod
{{ end }}
{{ if (eq $template "deployment.tmpl") }}
apiVersion: v1
kind: Deployment
metadata:
name: {{ .Name }}-deployment
spec:
replicas: {{ .Scale }}
template:
{{template "pod" dict "Version" $version "Domain" $domain "Image" $image "ImageDerived" $imageDerived "Service" . }}
回答3:
You can indent freely, but you need to use include
instead of template
, as template
is an action and can't be passed to other functions:
{{ include "pod" | indent 4 }}
See the Helm guide for more info.
回答4:
@Giovanni Bassi's answer only works in helm. The include
function is defined in helm here.
Combining with indent from sprig from @tmirks answer, you get:
func renderTemplate(templatePath string, vars interface{}, out io.Writer) error {
t := template.New(filepath.Base(templatePath))
var funcMap template.FuncMap = map[string]interface{}{}
// copied from: https://github.com/helm/helm/blob/8648ccf5d35d682dcd5f7a9c2082f0aaf071e817/pkg/engine/engine.go#L147-L154
funcMap["include"] = func(name string, data interface{}) (string, error) {
buf := bytes.NewBuffer(nil)
if err := t.ExecuteTemplate(buf, name, data); err != nil {
return "", err
}
return buf.String(), nil
}
t, err := t.Funcs(sprig.TxtFuncMap()).Funcs(funcMap).ParseFiles(templatePath)
if err != nil {
return err
}
err = t.Execute(out, &vars)
if err != nil {
return err
}
return nil
}
then
{{ include "pod" | indent 4 }}
来源:https://stackoverflow.com/questions/43821989/how-to-indent-content-of-included-template