How to indent content of included template

ぃ、小莉子 提交于 2019-12-20 03:07:08

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!