Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added "tpl" template function #2350

Merged
merged 6 commits into from Jun 12, 2017
Merged

Added "tpl" template function #2350

merged 6 commits into from Jun 12, 2017

Conversation

eicnix
Copy link
Contributor

@eicnix eicnix commented Apr 28, 2017

Added implementation for a tpl function that evaluates a string as a template.

Implementation for #1978

tplChart := &chart.Chart{
Metadata: &chart.Metadata{Name: "TplFunction"},
Templates: []*chart.Template{
{Name: "templates/base", Data: []byte(`Evaluate tpl {{tpl "Value: {{ .Values.value}}" .}}`)},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great!

Can you also test a template that uses template functions (like quote) and defined templates ({{ define "foo" }})? Something like tpl "Value: {{ .Values.value | quote }}" and tpl "{{ include 'foo' }}".

It looks like those should both work. But I think it's worth having a safety net in the tests. We need to be sure that now and in the future those two items are available within a nested template.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While testing the "include" function I ran into the following error since the other template is only available for the outer render context. Is there an global render context I could use to pass all registered templates to the rendering of the "tpl"-function?

tplChartWithInclude := &chart.Chart{
		Metadata: &chart.Metadata{Name: "TplFunction"},
		Templates: []*chart.Template{
			{Name: "templates/base", Data: []byte(`{{ tpl "{{include `+"`"+`TplFunction/templates/_partial`+ "`" + ` . | indent 2}}" .}}`)},
			{Name: "templates/_partial", Data: []byte(`{{.Release.Name}} - he`)},
		},
		Values:       &chart.Config{Raw: ``},
		Dependencies: []*chart.Chart{},

results in:

Expected "Evaluate tpl bar", got " template: no template \"TplFunction/templates/_partial\" associated with template \"gotpl\"" (map[TplFunction/templates/_partial:TestRelease - he TplFunction/templates/base: template: no template "TplFunction/templates/_partial" associated with template "gotpl"])

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll look into it. I was wondering about the scoping for that.

templates["template"] = r

result, err := e.render(templates)
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of returning the error as the result string I would favour making the function return (string, error) and failing the template execution altogether if the provided string does not render.

Otherwise errors are very hard to catch and will most certainly endup being deployed to k8s causing failures further down the road.

See the recently merged change for include #2358 for some more details.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the input. I changed the function to return an error on failure instead of writing it into the template.

eicnix added 2 commits May 2, 2017 09:44
…e error in the template

- Added tests for using a function inside a template that is evaluated using the "tpl" function
@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label May 2, 2017
@thomastaylor312 thomastaylor312 added this to the 2.5.0 - Features milestone May 6, 2017
templates := map[string]renderable{}
templates["template"] = r

result, err := e.render(templates)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if doing a t.Parse() here instead might cause it to inherit scope. I'm not sure how best to work around the loss of context...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a chart is rendered I add the Chart's templates as the current templates in the engine. If something else is rendered it will add the current templates to the render context.

@technosophos What do you think about it?

@technosophos
Copy link
Member

Is this ready for another review, @eicnix ?

@eicnix
Copy link
Contributor Author

eicnix commented Jun 8, 2017

@technosophos Yes, I am saving the current templates in the engine to reuse them in a tpl execution.
A test with uses an include inside a tpl is working.

@technosophos
Copy link
Member

Okay. It's on my docket for testing tomorrow for inclusion in 2.5.0.

@technosophos
Copy link
Member

Okay, I have done a lot of testing of this, and it seems to be in working order. Do you feel okay with my documenting this as an experimental feature for now? I am still a little worried that some strange edge case will crop up in production. But I am confident enough in this PR that I think we should ship it for 2.5.

@k8s-reviewable
Copy link

This change is Reviewable

}

templates := map[string]renderable{}
templates["aaa_template"] = r
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not mind changing this to a randomly generated string just to discourage others from trying to access the template directly. But that's definitely not necessary for now.

@eicnix
Copy link
Contributor Author

eicnix commented Jun 12, 2017

@technosophos Ofc this can be marked experimental. I don't fully understand the whole impact the caching could have and some real world feedback would be nice.

@technosophos
Copy link
Member

Okay! I'm merging this. Thanks again for the work on this @eicnix

@technosophos technosophos merged commit dece57e into helm:master Jun 12, 2017
@scjody
Copy link

scjody commented May 30, 2018

@eicnix Would it be possible for you to add some docs on what the tpl function does? As a Helm user I had trouble figuring this out and had to get help on Slack.

@eicnix
Copy link
Contributor Author

eicnix commented Jun 2, 2018

@scjody I added some documentation at #4160 . Would this documentation have been sufficient for you?

@scjody
Copy link

scjody commented Jun 5, 2018

Yes, that looks great, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. feature in progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants