Open breml opened 11 months ago
Not with template
, but we have a pattern like this for include
s:
{{ include (printf "%s" $template) . }}
It's certainly not as nice as having a dedicated function, but it works well enough for us.
@forquare Thanks for your contribution. I am not entirely sure I can follow your example. May I ask you to elaborate. In particular what is $template
(filename, name of the thing to include, the content to be included (plain text), the content to be included, but rendered as a Go template, something else) and what does the include
function exactly do. Thanks.
On a side note: Hugo does provide include functionality for Go templates, see https://gohugo.io/templates/introduction/#includes
@breml Firstly, let me apologise because I'm not sure how Helm does this, but I think they do some kind of preprocessing - I've tried this with my limited Go knowledge and can't replicate my suggestion simply using Go text/template
.
Secondly, apologies for not expanding. Despite the fact that what I said may not be valid! Let me still expand:
include
is a function in Helm which "will import the contents of a template into the present pipeline where it can be passed along to other functions in the pipeline" (from the Helm documentation here)
In my example, $template
is a variable containing the name of a named template, exactly the same as your first example. I had thought that your original example could have been rewritten like this:
{{ define "first" }} First {{ end }}
{{ $template := "first" }}
{{ template (printf "%s" $template) . }}
However I think you would need to have some sort of preprocessing in place to handle this, as my limited knowledge cant' replicate this simply in Go.
@forquare Thanks for the additional context. As you have written, include
is a function provided by helm (source code: https://github.com/helm/helm/blob/e81f6140ddb22bc99a08f7409522a8dbe5338ee3/pkg/engine/engine.go#L129), which works similar to the function yield
that I am proposing in this issue.
In the documentation you linked above there is a statement about template
, which explains why your snippet does not work:
Because template is an action, and not a function, there is no way to pass the output of a template call to other functions; the data is simply inserted inline.
The key is "template is an action, and not a function". Additionally to the limitation, that it does not allow the output to be passed to an other function, it is also more strict about the "arguments" it accepts. The first argument (name of the template) is required to be a string constant and it is not possible to pass the name of the template as a variable. The error, the template
action produces, if the name is not a string constant (but a variable) is provided in the initial description of this issue.
Both these limitations are removed by either the yield
function proposed here or the include
function available in helm.
With Go templates it is not possible to dynamically (based on a variable) include other templates (partials). For example the following is not a valid Go template:
and it will produce the following error:
Since I had this problem already multiple times, I created a function
yield
, which does the same astemplate
, but allows the template name (first argument) to by dynamic (it can be a variable).With the new function
yield
, the following becomes possible:I think, this would be a meaning full addition to https://github.com/Masterminds/sprig and I am happy to provide a PR for this. What do you think?