-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathviewengine_static.go
72 lines (56 loc) · 1.88 KB
/
viewengine_static.go
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
package xun
import (
"errors"
"io/fs"
"strings"
"github.com/yaitoo/xun/fsnotify"
)
// StaticViewEngine is a view engine that serves static files from a file system.
type StaticViewEngine struct {
}
// Load loads all static files from the given file system and registers them with the application.
//
// It scans the "public" directory in the given file system and registers each file
// with the application. It also handles file changes for the "public" directory
// and updates the application accordingly.
func (ve *StaticViewEngine) Load(fsys fs.FS, app *App) error {
err := fs.WalkDir(fsys, "public", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if !d.IsDir() {
ve.handle(fsys, app, path)
}
return nil
})
if err != nil && errors.Is(err, fs.ErrNotExist) {
return nil
}
return err
}
// FileChanged handles file changes for the given file system and updates the
// application accordingly. It is called by the watcher when a file is changed.
//
// If the file changed is a Create event and the path is in the "public" directory,
// it will be registered with the application.
//
// If the file changed is a Write/Remove event and the path is in the "public"
// directory, nothing will be done.
func (ve *StaticViewEngine) FileChanged(fsys fs.FS, app *App, event fsnotify.Event) error {
// Nothing should be updated for Write/Remove events.
if event.Has(fsnotify.Create) && strings.HasPrefix(event.Name, "public/") {
ve.handle(fsys, app, event.Name)
}
return nil
}
func (ve *StaticViewEngine) handle(fsys fs.FS, app *App, path string) {
name := strings.ToLower(path)
if strings.HasSuffix(name, "/index.html") { // remove it, because index.html will be redirected to ./ in http.ServeFileFS
name = name[:len(name)-10]
}
name = strings.TrimPrefix(name, "public/")
app.HandleFile(name, &FileViewer{
fsys: fsys,
path: path,
})
}