102 lines
2.3 KiB
Go
102 lines
2.3 KiB
Go
package tl
|
|
|
|
import (
|
|
"html/template"
|
|
"io/fs"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
// Template collection.
|
|
type Collection struct {
|
|
// Path to the directory with templates.
|
|
RootDir string
|
|
// By default, template name is it's path relative to [RootDir].
|
|
// This prefix will be prepended to a template name: Prefix + "/" + RelativePath.
|
|
// You can leave it empty, then it will be ignored.
|
|
Prefix string
|
|
}
|
|
|
|
// Advanced options.
|
|
type Options struct {
|
|
// Files from shared collections will be available in every main template.
|
|
SharedCollections []Collection
|
|
}
|
|
|
|
// Load templates from specified directories with default options.
|
|
// Files from the main collection will be added to the returned map.
|
|
func Load(mainCollection Collection) (map[string]*template.Template, error) {
|
|
return LoadWithOptions(mainCollection, Options{})
|
|
}
|
|
|
|
// Load templates from specified directories.
|
|
// Files from [mainTemplates] collection will be added to the returned map.
|
|
func LoadWithOptions(
|
|
mainCollection Collection,
|
|
options Options,
|
|
) (map[string]*template.Template, error) {
|
|
sharedTemplate := template.New("")
|
|
for _, stp := range options.SharedCollections {
|
|
files, err := getFiles(stp.RootDir, stp.Prefix)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for name, contents := range files {
|
|
sharedTemplate, err = sharedTemplate.New(name).Parse(contents)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
}
|
|
|
|
templateFiles, err := getFiles(mainCollection.RootDir, mainCollection.Prefix)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
res := make(map[string]*template.Template)
|
|
for name, contents := range templateFiles {
|
|
clone, err := sharedTemplate.Clone()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
res[name], err = clone.New(name).Parse(contents)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func getFiles(root string, keyPrefix string) (map[string]string, error) {
|
|
res := make(map[string]string)
|
|
if !strings.HasSuffix(root, "/") {
|
|
root += "/"
|
|
}
|
|
|
|
err := filepath.WalkDir(root, func(entrypath string, d fs.DirEntry, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if d.IsDir() {
|
|
return nil
|
|
}
|
|
|
|
shortPath := path.Join(keyPrefix, strings.TrimPrefix(entrypath, root))
|
|
contents, err := os.ReadFile(entrypath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
res[shortPath] = string(contents)
|
|
return nil
|
|
})
|
|
|
|
return res, err
|
|
}
|