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

Adding support for Go 1.16's FS interface #191

Open
advdv opened this issue Mar 18, 2021 · 5 comments
Open

Adding support for Go 1.16's FS interface #191

advdv opened this issue Mar 18, 2021 · 5 comments

Comments

@advdv
Copy link

advdv commented Mar 18, 2021

Go 1.16 introduces the fs package and a FS interface. Implementing a Jet loader for this seems like an ideal use case. Are there any plans for this, would it be easy?

EDIT: actually, maybe it is as simple as this?

type StdFileSystemLoader struct{ fs.FS }

func (l StdFileSystemLoader) Open(templatePath string) (io.ReadCloser, error) {
	return l.FS.Open(templatePath)
}

func (l StdFileSystemLoader) Exists(templatePath string) bool {
	_, err := l.Open(templatePath)
	return err == nil && !os.IsNotExist(err)
}
@sauerbraten
Copy link
Collaborator

Yes, that adapter should be all you need to use 1.16's FS interface!
Let me know if it works, It probably makes sense to have this boilerplate directly in Jet.

@advdv
Copy link
Author

advdv commented Mar 25, 2021

I actually just found a way to do this without an extra type by using jets loaders/httpfs package:

//go:embed *.html
var tfs embed.FS

// loader allows for loading templates
func loader() (jet.Loader, error) {
	return httpfs.NewLoader(http.FS(tfs))
}

it is a bit weird to require a "httpfs/http" package for something that just have to deal with filesystems but it works as expected.

@replay111
Copy link

replay111 commented Sep 27, 2021

@advanderveer How did you pass this func loader to Jet Engine so it is loading files from tfs ?

I have someting like this:
main.go:

//go:embed templates
var assets embed.FS //stored in: Repo.App.TemplatesFS

handlers.go:

var view = jet.NewSet(
	jet.NewOSFileSystemLoader("./templates"),
	jet.InDevelopmentMode(), // remove in production
)

func loader() (jet.Loader, error) {
	return httpfs.NewLoader(http.FS(Repo.App.TemplatesFS))
}

but I have no idea how to link this together :-)

@replay111
Copy link

Hello again,

I've tried this way:

var view *jet.Set

func init() {
	httpFsLoader, err := loader()
	if err != nil {
		log.Panicln("error: ", err)
	}
	view = jet.NewSet(
		httpFsLoader,
		jet.InDevelopmentMode(),
	)
}

func loader() (jet.Loader, error) {
	return httpfs.NewLoader(http.FS(Repo.App.TemplatesFS))
}

where Repo.App.TemplatesFS stores:

type ApplicationConfig struct {
	InfoLog       *log.Logger
	ErrorLog      *log.Logger
	InDevelopment bool
	Session       *scs.SessionManager
	TemplatesFS   embed.FS
}

//go:embed templates
var assets embed.FS
var app config.ApplicationConfig

app.TemplatesFS = assets

But compiler does not like this part:

func loader() (jet.Loader, error) {
	return httpfs.NewLoader(http.FS(Repo.App.TemplatesFS))
}

error:
cannot use httpfs.NewLoader(http.FS(Repo.App.TemplatesFS)) (value of type jet.Loader) as jet.Loader value in return statement: wrong type for method Open (have func(templatePath string) (io.ReadCloser, error), want func(templatePath string) (io.ReadCloser, error))compilerInvalidIfaceAssign

but Repo.App.TemplatesFS is embed.FS so it is the same type as in example from @advanderveer

@replay111
Copy link

replay111 commented Sep 29, 2021

Ok I also found solution for my case:

func InitTemplateSystem(assets embed.FS) *jet.Set {
	httpFsLoader, err := httpfs.NewLoader(http.FS(assets))
	if err != nil {
		log.Panicln("error: ", err)
	}
	return jet.NewSet(httpFsLoader, jet.InDevelopmentMode())
}

the error was caused by wrong import - VSCode is suggesting:

	"github.com/CloudyKit/jet/v6"
	"github.com/CloudyKit/jet/loaders/httpfs"

instead of:

	"github.com/CloudyKit/jet/v6"
	"github.com/CloudyKit/jet/v6/loaders/httpfs"

Now I am calling: app.View = handlers.InitTemplateSystem(web.WebFiles) in my main.go file and initialize once Jet engine. Web files are loaded in "./web/web.go" module:

import "embed"

//go:embed templates
var WebFiles embed.FS

which is on the same level as templates directory.

Maybe not the best solution (because of passing Jet engine to app config - which I do not like very much for now) but for the beginning I think it is ok. When I learn more then problably will change that to maybe something more sophisticated.

ryanlath added a commit to ryanlath/jet that referenced this issue Mar 3, 2024
sauerbraten pushed a commit that referenced this issue Mar 7, 2024
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