-
Notifications
You must be signed in to change notification settings - Fork 18k
proposal: text/template: add ability to send executed content to a pipeline #54748
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
Comments
cc @robpike |
I have a draft in my TODOs to propose a similar feature. Compared to, say, classic Mustache-style (see also ERB, Django, Jinja, etc.) templates, the Go templating system is pretty similar, if superficially different in some ways. But compared to newer React, Vue, etc. style component template systems, Go is missing a key ability: the ability to send children out for further processing. A hypothetical React template might looks like <div>
<p>Normal template stuff. Some variable { val }.</p>
<Button kind="also normal and doable" value={otherVal} />
<ButtonGroup>
<h2>Whoa, new capability</h2>
<p>This button group has children!</p>
<Button kind="etc" value={otherVal} />
<Button kind="etc" value={otherVal} />
</ButtonGroup>
</div> In the function for ButtonGroup, the h2, p, and Buttons get passed in as the argument You can do the equivalent interpolation in Go with |
Here is another fork of Go templates that add component-like functionality: https://github.com/philippta/go-template In this case, the repo adds
|
My proposal really isn't about component-like functionality, although you can implement component-like functionality within my proposal. The whole idea of "components" is too much of an HTML / React / web dev idea to fit within text/template anyway. I believe my proposal is still useful even for unstructured text, and a web-focused system like Hugo could easily implement "components" on top, e.g.
|
I think your proposal is a more general solution that gets at the same problem. Just having the ability to do |
|
I agree. I think there are two things that need to be exposed: the ability to treat a rendered template as a value so that it can be piped through e.g. markdown and passed to other templates and the ability to create a block of content in situ without needing an external definition. I wonder if it would be possible to change the existing
|
This makes it possible to: * modularize a template by using an embedded template (defined with Go's built-in `define` action) as a function whose return value is the expansion of the template * post-process the expansion of a template (e.g., pipe it to Sprig's `indent` function) For additional context, see <golang/go#54748>. Sprig is unlikely to add an equivalent to this function any time soon: the function must be a closure around the template, meaning either Sprig or Go would have to change its API.
This makes it possible to: * modularize a template by using an embedded template (defined with Go's built-in `define` action) as a function whose return value is the expansion of the template * post-process the expansion of a template (e.g., pipe it to Sprig's `indent` function) For additional context, see <golang/go#54748>. Sprig is unlikely to add an equivalent to this function any time soon: the function must be a closure around the template, meaning either Sprig or Go would have to change its API.
This makes it possible to: * modularize a template by using an embedded template (defined with Go's built-in `define` action) as a function whose return value is the expansion of the template * post-process the expansion of a template (e.g., pipe it to Sprig's `indent` function) For additional context, see <golang/go#54748>. Sprig is unlikely to add an equivalent to this function any time soon: the function must be a closure around the template, meaning either Sprig or Go would have to change its API.
I propose adding an
apply
function to text/template which would execute a template and send its output to a pipeline:The motivation for this feature is essentially the same as the motivation for Hugo's shortcodes. When authoring content in Go templates, it is often desirable to run templated content through a template function for post-processing - for example, for syntax highlighting, processing markdown, creating "accordion" sections, etc.
Different flavors of this behavior have been proposed before (see below), and have been rejected with workarounds. Unfortunately, the best workaround available today is to add an
eval "template name" .
function and then use named templates, which is too cumbersome in practice:I propose for
apply
to simply be sugar for this workaround, albeit without defining a named template. With the proposed feature, this example would look like:I have created a prototype implementation of this feature.
Prior proposals
This issue proposed modifications to the behavior of
block
andtemplate
which were deemed unacceptable. A workaround was suggested where the user can supply aneval
function to execute a named template and get its result as a value. Unfortunately this workaround is still too cumbersome for the workflows described in this proposal.This issue was, in my opinion, erroneously closed as a duplicate of the previous issue. However, it did not redefine any existing syntax, so it was not really proposing the same thing. I hope that my proposal is a more complete and thoughtful version of this idea.
Open questions
Is this API sufficient? It may be wise to additionally expose APIs like the following, but I will leave that for further discussion.
eval "template name" .
: evaluates a template by name and returns the output as a string. This behavior is implicitly present inapply
, and is part of the commonly-suggested workaround, so it may be worth exposing explicitly. Example:The text was updated successfully, but these errors were encountered: