如何缩进包含模板的内容

huangapple go评论104阅读模式
英文:

How to indent content of included template

问题

我正在使用go模板为Kubernetes创建yaml定义。我尝试嵌套模板,但遇到了一个问题,即当包含的定义的缩进错误时,我无法简单地重用它。也就是说,在某些情况下,内容需要缩进,而在其他情况下则不需要。我该如何控制包含内容的缩进?

以下是示例。我正在重用pod.tmpl,在第一种情况下,它可以直接包含。在第二种情况下,我需要缩进整个内容,使其成为service的成员。

{{ if (eq .Case "pod") }}
  # 不需要缩进
  {{ template "pod" }}
{{ end }}

{{ if (eq .Case "service") }}
  service:
    # 需要缩进!使内容成为service的成员:
    {{ template "pod" }}
{{ end }}
英文:

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

得分: 8

@Giovanni Bassi的答案只适用于Helm。include函数在helm这里中定义。

结合@tmirks的答案中的sprig中的indent,你可以得到以下代码:

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
}

然后使用以下代码:

{{ include "pod" | indent 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 }}

答案2

得分: 2

你可以自由缩进,但需要使用include而不是template,因为template是一个动作,不能传递给其他函数:

<!-- language-all: go-template -->

{{ include "pod" | indent 4 }}

有关更多信息,请参阅Helm指南

英文:

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:

<!-- language-all: go-template -->

{{ include &quot;pod&quot; | indent 4 }}

See the Helm guide for more info.

答案3

得分: 1

你应该能够将模板的输出导入到sprig包中提供的indent函数中:

<!-- language-all: go-template -->

{{ if (eq .Case "service")
  service:
    # 需要缩进!这样内容就成为service的成员:
{{ template "pod" | indent 4 }}
{{ end }}
英文:

You should be able to pipe the output of your template to the indent function available in the sprig package:

<!-- language-all: go-template -->

{{ if (eq .Case &quot;service&quot;)
  service:
    # need to indent! so contents become members of service:
{{ template &quot;pod&quot; | indent 4 }}
{{ end }}

答案4

得分: 0

我发现如果我将pod.tmpl的内容缩进,然后将顶部部分缩进以对齐,我可以解决这个问题,如下所示:

{{ 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" . }}
英文:

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 &quot;pod.tmpl&quot;) }}
    apiVersion: v1
    kind: Pod
{{ end }}
{{ if (eq $template &quot;deployment.tmpl&quot;) }}
apiVersion: v1
kind: Deployment
metadata:
  name: {{ .Name }}-deployment
spec:
  replicas: {{ .Scale }}
  template:
{{template &quot;pod&quot; dict &quot;Version&quot; $version &quot;Domain&quot; $domain &quot;Image&quot; $image &quot;ImageDerived&quot; $imageDerived &quot;Service&quot; . }}

huangapple
  • 本文由 发表于 2017年5月6日 23:07:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/43821989.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定