Created
December 25, 2023 09:29
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As a library https://github.com/reddec/view