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

NewTemplateFileSystem for fileb0x (similar to vfsgen, assetfs, etc) #3

Open
coolaj86 opened this issue Oct 25, 2018 · 0 comments
Open

Comments

@coolaj86
Copy link

coolaj86 commented Oct 25, 2018

I needed to use macaron.Render with fileb0x instead of bindata. I think that this code will be helpful for anyone who might need to use vfsgen, packr, statik, rice and other bindata-style systems.

package router

import (
	"bytes"
	"fmt"
	"io"
	"path/filepath"

	"code.example.com/me/go-static"

	"gopkg.in/macaron.v1"
)

// Replace the one from macaron.Render since the files field is private
// TplFileSystem implements TemplateFileSystem interface.
type TplFileSystem struct {
	files []macaron.TemplateFile
}

// NewTemplateFileSystem creates new template file system with given options.
func NewTemplateFileSystem(lastDir string, exts ...string) macaron.TemplateFileSystem {
	fs := TplFileSystem{}
	fs.files = make([]macaron.TemplateFile, 0, 10)
	if 0 == len(exts) {
		exts = []string{".tmpl", ".html"}
	}

	// This is the fileb0x WalkDirs
	paths, _ := static.WalkDirs(lastDir, false)
	for _, path := range paths {
		r, err := filepath.Rel(lastDir, path)
		ext := macaron.GetExt(r)

		for _, extension := range exts {
			if ext != extension {
				continue
			}

			var data []byte
			// Loop over candidates of directory, break out once found.
			// The file always exists because it's inside the walk function,
			// and read original file is the worst case.
			path = filepath.Join(lastDir, r)
			data, err = static.ReadFile(path)
			if err != nil {
				panic(err)
			}

			name := filepath.ToSlash((r[0 : len(r)-len(ext)]))
			fs.files = append(fs.files, macaron.NewTplFile(name, data, ext))
		}
	}

	return fs
}

func (fs TplFileSystem) ListFiles() []macaron.TemplateFile {
	return fs.files
}

func (fs TplFileSystem) Get(name string) (io.Reader, error) {
	for i := range fs.files {
		if fs.files[i].Name()+fs.files[i].Ext() == name {
			return bytes.NewReader(fs.files[i].Data()), nil
		}
	}
	return nil, fmt.Errorf("file '%s' not found", name)
}

This could probably be updated to use a generic interface that would work with many different FileSystem implementations and be created as a PR. However, for now I'll just leave this an example that others can easily follow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant