-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathengine_loading.go
More file actions
146 lines (128 loc) · 3.86 KB
/
engine_loading.go
File metadata and controls
146 lines (128 loc) · 3.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package gotmx
import (
"bufio"
"io/fs"
"os"
"path/filepath"
)
// LoadHTML parses HTML string(s) and registers any template definitions found.
// Templates are available immediately after this call.
// Returns an error if parsing fails.
func (e *Engine) LoadHTML(html string) error {
loader := newTemplateLoaderString(e.registry)
loader.SetLogger(e.config.logger)
return loader.LoadFromString(html, "inline")
}
// LoadFile parses a single HTML file and registers any template definitions.
// The file path becomes the namespace for the templates.
func (e *Engine) LoadFile(path string) error {
file, err := os.Open(path)
if err != nil {
return err
}
defer func() { _ = file.Close() }()
reader := bufio.NewReader(file)
normalizedPath := filepath.ToSlash(path)
return loadTemplateFromReader(e.registry, reader, normalizedPath)
}
// LoadFS loads templates from a filesystem with an optional prefix.
// Useful for the registration pattern where packages register their own templates.
// The prefix is prepended to template namespaces for disambiguation.
//
// engine.LoadFS(users.TemplateFS, "users") // templates namespaced as "users/..."
// engine.LoadFS(shared.TemplateFS, "") // no prefix
func (e *Engine) LoadFS(fsys fs.FS, prefix string) error {
loader := newTemplateLoaderHTML(fsys, e.registry)
loader.SetLogger(e.config.logger)
// Walk the filesystem and load all templates
return fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
// Skip directories
if d.IsDir() {
return nil
}
// Only process .htm files (eager loading)
ext := filepath.Ext(path)
if ext == ".htm" {
// Prepend prefix if provided
sourcePath := path
if prefix != "" {
sourcePath = prefix + "/" + path
}
// Load the file
data, err := fs.ReadFile(fsys, path)
if err != nil {
return err
}
loaderString := newTemplateLoaderString(e.registry)
loaderString.SetLogger(e.config.logger)
return loaderString.LoadFromString(string(data), sourcePath)
}
return nil
})
}
// Preload forces immediate loading of templates matching the given patterns.
// Useful for preloading critical templates while keeping others lazy.
// Patterns support glob syntax: "components/*.htm", "layouts/**/*.html"
func (e *Engine) Preload(patterns ...string) error {
// For each configured source, load templates matching patterns
for _, pattern := range patterns {
if err := e.preloadPattern(pattern); err != nil {
return err
}
}
return nil
}
// preloadPattern loads templates matching a single pattern.
func (e *Engine) preloadPattern(pattern string) error {
// Try to load from configured template directories
for _, dir := range e.config.templateDirs {
matches, err := filepath.Glob(filepath.Join(dir, pattern))
if err != nil {
return err
}
for _, match := range matches {
if err := e.LoadFile(match); err != nil {
return err
}
}
}
// Try to load from configured filesystems
for _, fsys := range e.config.fsystems {
if err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
// Check if path matches the pattern
matched, err := filepath.Match(pattern, path)
if err != nil {
return err
}
if matched {
data, err := fs.ReadFile(fsys, path)
if err != nil {
return err
}
loaderString := newTemplateLoaderString(e.registry)
loaderString.SetLogger(e.config.logger)
return loaderString.LoadFromString(string(data), path)
}
return nil
}); err != nil {
return err
}
}
return nil
}
// RegisterFunc registers a function for use in Go templates.
// Must be called before templates using the function are parsed.
func (e *Engine) RegisterFunc(name string, fn any) {
if goReg, ok := e.registry.(GoTemplateRegistry); ok {
goReg.RegisterFunc(name, fn)
}
}