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

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

Open
timhanus opened this issue Sep 23, 2019 · 4 comments

Comments

@timhanus
Copy link

timhanus commented Sep 23, 2019

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.

@osteele
Copy link
Owner

osteele commented Oct 28, 2019

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.

@timhanus
Copy link
Author

No worries. Glad you like the suggestion.

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

@osteele
Copy link
Owner

osteele commented Jun 17, 2021

PR #41 could use this

@chrisatbd
Copy link

chrisatbd commented May 2, 2024

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.

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

3 participants