Checklist
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
}
Checklist
IsTemplateErrorreturns 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
Actual Behavior
The
renderpackage has aRender(node Node, w io.Writer, vars map[string]interface{}, c Config)function which takes anio.Writer, however, this is meant for internal use only. TheTemplatemethods haveRender(vars Bindings) ([]byte, SourceError)andRenderString(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
Templaterender methodFRenderthat allows to pass a customio.Writer: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: