Create a "FileSystem" abstraction to allow loading of templates from DB/URLs/etc
Summary
The ruby implementation of liquid defines a "FileSystem" interface than can be used to load template files from sources other than the local disk. This allows a developer to (for example) load template files from s3 buckets or a database seamlessly. This feature becomes particularly useful when using include tags.
https://github.com/Shopify/liquid/blob/master/lib/liquid/file_system.rb https://www.rubydoc.info/gems/liquid/Liquid/BlankFileSystem
I have an unfinished version of this working locally, but wanted to submit this issue for discussion before I got too far down any particular implementation path.
Suggested Implementation
Trying to stay as close as possible to the ruby implementation we define an interface as:
type LiquidFileSystem interface {
ReadTemplateFile(templatename string) ([]byte, error)
}
The instance of LiquidFileSystem lives in the render.config struct. A basic implementation (and default behavior to provide backwards compatibility) would be a simple wrapper around ioutil.ReadFile
func (tl *diskFileSystem) ReadTemplateFile(filename string) ([]byte, error) {
source, err := ioutil.ReadFile(filename)
return source, err
}
Any custom implementation would be utilized as follows:
type S3FileSystem struct { ...snip... }
func NewS3FileSystem(...) *S3FileSystem { ...snip... }
func (tl *S3FileSystem) ReadTemplateFile(filename string) ([]byte, error) { ... snip ...}
e := liquid.NewEngine()
fs := NewS3FileSystem(...)
e.RegisterFilesystem(fs)
As yet Unaddressed Issues
- Template Error Reporting (currently I believe we just report filename as opposed to a full URL)
- Potentially new classes of errors?
- Caching. Another github issue addresses caching, but it becomes more important if we are loading templates files from a relatively high latency source.
Next Steps/Suggestions?
If this approach seems generally sane to you and it's a feature you are interested in adding I will finish cleaning up the code and submit a PR. If you have any alternate implementation ideas I'm more than open to incorporating them.
This looks like a very well-thought-out proposal and I'd be happy to have it in the project.
I'm sorry for the very long delay in my reply, and I hope you're still interested.
No worries. Glad you like the suggestion.
I'll try to finish this up and submit a PR soon.
PR #41 could use this
Not sure where this got left, but we needed some similar functionality and created an implementation similar to what @timhanus suggests.
Here is where the updates can be found
https://github.com/chrisatbd/liquid/tree/contribute/template-loader
It is not completely polished off, but would love to contribute back to the project if interested.