Search code examples
gotemplatesgo-templates

How to render a "template of templates", without escaping each action


Does anyone know how to render a "template of templates" with text/template, where only specific actions (ie: things wrapped in {{...}}) will be rendered, and the rest will be treated as literals?

For example, given the following template:

I want to render {{.Foo}}.

but I don't want to render anything on this line, like {{.Bar}} or this template: [{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .CommonLabels.alertname }} for {{ .CommonLabels.job }}

Render {{.Foo}} again.

I want to render the following output:

I want to render foo.

but I don't want to render anything on this line, like {{.Bar}} or this template: [{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .CommonLabels.alertname }} for {{ .CommonLabels.job }}

Render foo again.

While I can escape each portion of my desired literal with {{ "{{" }}, it feels a bit tedious.

I imagine that I should be able to do something like I want to render {{template "outer" .Foo}}. and call something like tmpl.ExecuteTemplate(&buff, "outer", data) to only render my specified "outer" actions.

I also wonder if rendering a "template of templates" is a code smell, and I should replace my "outer" template with a string/replace if possible, like I want to render <<.Foo>>.


Solution

  • You can change the delimiters for the first level of template:

    tmpl := template.New("name").Delims("<<",">>").Parse(...)
    

    Then, write the template as:

    I want to render <<.Foo>>.
    
    but I don't want to render anything on this line, like {{.Bar}}...