liquid icon indicating copy to clipboard operation
liquid copied to clipboard

Create a "FileSystem" abstraction to allow loading of templates from DB/URLs/etc

Open timhanus opened this issue 6 years ago • 4 comments

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

  1. Template Error Reporting (currently I believe we just report filename as opposed to a full URL)
  2. Potentially new classes of errors?
  3. 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.

timhanus avatar Sep 23 '19 18:09 timhanus

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.

osteele avatar Oct 28 '19 01:10 osteele

No worries. Glad you like the suggestion.

I'll try to finish this up and submit a PR soon.

timhanus avatar Oct 29 '19 15:10 timhanus

PR #41 could use this

osteele avatar Jun 17 '21 06:06 osteele

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.

chrisatbd avatar May 02 '24 17:05 chrisatbd