Skip to content

Instantly share code, notes, and snippets.

@reddec
Created December 25, 2023 09:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save reddec/312367d75cc03f1ee49bae74c52a6b31 to your computer and use it in GitHub Desktop.
Save reddec/312367d75cc03f1ee49bae74c52a6b31 to your computer and use it in GitHub Desktop.
Load a single template (view) along with all layouts (_layout.gohtml) from directories, starting from the top and going down to the current directory
package web
import (
"errors"
"fmt"
"html/template"
"io/fs"
"os"
"path"
"strings"
)
// LoadFS is the same as Load but using new empty template as root.
func LoadFS(store fs.FS, view string) (*template.Template, error) {
return Load(template.New(""), store, view)
}
// Load single template (view) and all layouts (_layout.gohtml) from all dirs starting from the top
// and until the current dir.
//
// If embedded FS is used, glob suffix in go:embed (/** or *) MUST be used, otherwise files with underscore will
// not be included by Go compiler.
func Load(root *template.Template, store fs.FS, view string) (*template.Template, error) {
const layoutName = "_layout.gohtml"
dirs := strings.Split(strings.Trim(view, "/"), "/")
dirs = dirs[:len(dirs)-1] // last segment is view itself
// parse layouts from all dirs starting from the top and until the current dir
for i := range dirs {
fpath := path.Join(path.Join(dirs[:i+1]...), layoutName)
content, err := fs.ReadFile(store, fpath)
if errors.Is(err, os.ErrNotExist) || errors.Is(err, fs.ErrNotExist) {
continue // layout does not exists - skipping
}
if err != nil {
return nil, fmt.Errorf("read layouad %q: %w", fpath, err)
}
child, err := root.Parse(string(content))
if err != nil {
return nil, fmt.Errorf("parse %q: %w", fpath, err)
}
root = child
}
// parse view it self
content, err := fs.ReadFile(store, view)
if err != nil {
return nil, fmt.Errorf("parse view %q: %w", view, err)
}
return root.Parse(string(content))
}
@reddec
Copy link
Author

reddec commented Jan 11, 2024

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