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

Add FRender to allow rendering into a custom io.Writer #85

Open
1 of 2 tasks
jamslinger opened this issue Apr 26, 2024 · 0 comments
Open
1 of 2 tasks

Add FRender to allow rendering into a custom io.Writer #85

jamslinger opened this issue Apr 26, 2024 · 0 comments

Comments

@jamslinger
Copy link
Contributor

Checklist

  • I have searched the issue list
  • I have tested my example against Shopify Liquid. (This isn't necessary if the actual behavior is a panic, or an error for which IsTemplateError returns false.)

Expected Behavior

This proposal originated from #35 but tries to tackle a broader issue, i.e.: Sometimes I might want to have more control over the rendering process, specifically where the renderer writes to.

Example

  • I might want to limit the number of bytes written when exposing templating to some untrusted party.
  • I might want to set a timeout for the rendering process.
  • I might want to render into a file directly.

Actual Behavior

The render package has a Render(node Node, w io.Writer, vars map[string]interface{}, c Config) function which takes an io.Writer, however, this is meant for internal use only. The Template methods have Render(vars Bindings) ([]byte, SourceError) and RenderString(b Bindings) (string, SourceError) which are useful in most circumstances but don't allow for more control as described above.

Detailed Description

Possible Solution

I'd propose a new Template render method FRender that allows to pass a custom io.Writer:

func (t *Template) FRender(w io.Writer, vars Bindings) SourceError

This gives more control over the rendering process when needed, e.g. you might want to set a render timeout to avoid deeple nested loop constructs in a template to cause potential server issues:

type CancelWriter struct {
	context.Context
	bytes.Buffer
}

func (w *CancelWriter) Write(bs []byte) (int, error) {
	if w.Err() != nil {
		return w.Len(), context.Cause(w)
	}
	return w.Buffer.Write(bs)
}

func Render() ([]byte, error) {
	wr := &CancelWriter{}
	if err := liquid.NewEngine().ParseAndFRender(wr, nil /*untrustworthy template*/, nil /*data*/); err != nil {
		return nil, err
	}
	return wr.Bytes(), nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant