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

proposal: text/template: struct tags #47663

Closed
ainsleyclark opened this issue Aug 12, 2021 · 12 comments
Closed

proposal: text/template: struct tags #47663

ainsleyclark opened this issue Aug 12, 2021 · 12 comments

Comments

@ainsleyclark
Copy link

ainsleyclark commented Aug 12, 2021

Proposal:

It would be great if we could assign template tags to a struct so we can hide them from public view or rewrite the name when executing a template.
On many occasions we have to create a Public method. Having a tag similar to json on the struct would make so much sense.

I'm not sure if this has been discussed before but an example is below:

Example

File struct {
	URL        string            `json:"url" template:"URL"`
	Name       string            `json:"name" template: "-"`
}

Thank you.

@gopherbot gopherbot added this to the Proposal milestone Aug 12, 2021
@seankhliao seankhliao changed the title Proposal: Template Tags proposal: text/template: struct tags Aug 12, 2021
@seankhliao
Copy link
Member

cc @robpike

@ianlancetaylor
Copy link
Member

I'm not sure what this tag means. Can you give an example of how this would be used? Thanks.

@ainsleyclark
Copy link
Author

ainsleyclark commented Aug 12, 2021

Sure.

So the File struct (as an example) has a field called URL, but when it is being used in a template, it transforms into
{{ .Example }} as defined on the stuct tag. Similarly, the dash ensures that no one can use the {{ .Name }} field within the template, as we are making it private.

type File struct {
	URL        string            `json:"url" template:"example"`
	Name       string            `json:"name" template: "-"`
}

func Test() error {
	str := "{{ .Example }}"
	
	tpl, err := template.New("").Parse(str)
	if err != nil {
		return err
	}
	
	f := File{
		URL:  "myurl",
		Name: "name", // Private, no one can access it when executing a tpl.
	}
	
	buf := bytes.Buffer{}
	err = tpl.Execute(&buf, f)
	if err != nil {
		return err
	}
	
	// Would output `myurl`
	
	return nil
}

Hope that makes sense.

@ianlancetaylor
Copy link
Member

I'm sorry, I don't understand why this is useful. Templates aren't like JSON, where Go code has to conform to externally defined data formats that were not designed with Go in mind. Templates are only used with Go code. Why do we need a translation layer from Go code to Go code?

@ainsleyclark
Copy link
Author

I can see where you are coming from but more often that not when you are exporting information to a template 9 times out of 10 you have to transform it in one way or another.
Having it as a struct tag does exactly that.

@ianlancetaylor
Copy link
Member

more often that not when you are exporting information to a template 9 times out of 10 you have to transform it in one way or another.

I don't understand why that would be true. Can you point to a couple of examples in existing open source packages? Thanks.

@earthboundkid
Copy link
Contributor

Nitpick:

type File struct {
	URL        string            `json:"url" template:"example"`
	Name       string            `json:"name" template: "-"`
}

func Test() error {
	str := "{{ .Example }}"

Surely this should be {{ .example }}. If you wanted {{ .Example }} your struct tag should be template:"Example".


This proposal makes the most sense with user provided or otherwise external templates, but in general templates are taken from trusted sources, so it's little bit of an odd usecase.

I bet you could write something that uses package reflect to create a map[string]interface{} based on the struct tags and use it like this:

	f := File{
		URL:  "myurl",
		Name: "name", // Private, no one can access it when executing a tpl.
	}
	
	buf := bytes.Buffer{}
	err = tpl.Execute(&buf, MyConverter(f))

@rsc
Copy link
Contributor

rsc commented Aug 25, 2021

This proposal has been added to the active column of the proposals project
and will now be reviewed at the weekly proposal review meetings.
— rsc for the proposal review group

@robpike
Copy link
Contributor

robpike commented Aug 25, 2021

I do not understand the purpose of this proposal. The programmer is already in control of the names in the struct and in the template and there is no information leak that needs to be shut down.

@rsc
Copy link
Contributor

rsc commented Sep 1, 2021

Based on the discussion above, this proposal seems like a likely decline.
— rsc for the proposal review group

@ainsleyclark
Copy link
Author

No worries thanks for considering

@rsc
Copy link
Contributor

rsc commented Sep 8, 2021

No change in consensus, so declined.
— rsc for the proposal review group

@rsc rsc closed this as completed Sep 8, 2021
@rsc rsc moved this to Declined in Proposals Aug 10, 2022
@rsc rsc added this to Proposals Aug 10, 2022
@golang golang locked and limited conversation to collaborators Sep 8, 2022
@rsc rsc removed this from Proposals Oct 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants