mirror of
https://github.com/Theodor-Springmann-Stiftung/musenalm.git
synced 2025-10-28 16:55:32 +00:00
104 lines
2.1 KiB
Go
104 lines
2.1 KiB
Go
package templating
|
|
|
|
import (
|
|
"io/fs"
|
|
"log/slog"
|
|
"path/filepath"
|
|
"slices"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
// TODO: redo template parsing to allow for just rendering single components
|
|
type File struct {
|
|
Name string
|
|
Path string
|
|
Ext string
|
|
}
|
|
|
|
func FromDirEntry(entry fs.DirEntry, path string) File {
|
|
ext := filepath.Ext(entry.Name())
|
|
Name := strings.TrimSuffix(entry.Name(), ext)
|
|
return File{
|
|
Name: Name,
|
|
Ext: ext,
|
|
Path: path,
|
|
}
|
|
}
|
|
|
|
type Directory struct {
|
|
Path string
|
|
Locals map[string]File
|
|
Globals map[string]File
|
|
}
|
|
|
|
type Templates struct {
|
|
Directories sync.Map // map[string]*Directory
|
|
}
|
|
|
|
func (t *Templates) NewDirectory(path string, fsys fs.FS) (*Directory, error) {
|
|
fspath := PathToFSPath(path)
|
|
entries, err := fs.ReadDir(fsys, fspath)
|
|
|
|
wg := &sync.WaitGroup{}
|
|
|
|
if err != nil {
|
|
return nil, NewError(FileAccessError, fspath)
|
|
}
|
|
|
|
dir := &Directory{}
|
|
for _, file := range entries {
|
|
if file.IsDir() && file.Name() == TEMPLATE_COMPONENT_DIRECTORY {
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
locals, globals, err := t.ScanComponentDirectory(filepath.Join(fspath, file.Name()), fsys)
|
|
if err != nil {
|
|
slog.Error("Failed to scan component directory", "path", file.Name(), "error", err)
|
|
return
|
|
}
|
|
dir.Locals = locals
|
|
dir.Globals = globals
|
|
}()
|
|
}
|
|
|
|
if !slices.Contains(TEMPLATE_FORMATS, filepath.Ext(file.Name())) {
|
|
continue
|
|
}
|
|
|
|
}
|
|
|
|
wg.Wait()
|
|
return dir, nil
|
|
}
|
|
|
|
func (t *Templates) ScanComponentDirectory(path string, fsys fs.FS) (map[string]File, map[string]File, error) {
|
|
locals := make(map[string]File)
|
|
globals := make(map[string]File)
|
|
fspath := PathToFSPath(path)
|
|
err := fs.WalkDir(fsys, fspath, func(path string, d fs.DirEntry, err error) error {
|
|
if err != nil {
|
|
return NewError(FileAccessError, path)
|
|
}
|
|
|
|
if d.IsDir() || !slices.Contains(TEMPLATE_FORMATS, filepath.Ext(d.Name())) {
|
|
return nil
|
|
}
|
|
|
|
f := FromDirEntry(d, path)
|
|
if strings.HasPrefix(f.Name, TEMPLATE_GLOBAL_PREFIX) {
|
|
globals[f.Name] = f
|
|
} else {
|
|
locals[f.Name] = f
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return nil, nil, NewError(FileAccessError, path)
|
|
}
|
|
|
|
return locals, globals, nil
|
|
}
|