-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy paththeme.go
108 lines (91 loc) · 2.42 KB
/
theme.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
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
package main
import (
"github.com/hoisie/mustache"
"github.com/howeyc/fsnotify"
"log"
"strings"
)
type ThemeRequest struct {
template string
data interface{}
}
type ThemeEngine struct {
watcher *fsnotify.Watcher
templates map[string]*mustache.Template
done chan bool
request chan ThemeRequest
response chan string
}
func makeThemeFileName(name string) string {
return "./static/theme/" + name + ".tmpl.html"
}
func NewThemeEngine() (*ThemeEngine, error) {
w, err := fsnotify.NewWatcher()
if err != nil {
return nil, err
}
t := ThemeEngine{w, make(map[string]*mustache.Template), make(chan bool, 1), make(chan ThemeRequest, 1), make(chan string, 1)}
files := []string{"layout", "article", "page", "list"}
for _, f := range files {
path := makeThemeFileName(f)
t.loadTemplate(path)
}
//fsnotify can't handle delete/rename
//so we work around that by watching
//the directory
t.watcher.Watch("./static/theme")
return &t, nil
}
func (t *ThemeEngine) ThemeArticle(a *Article) string {
return t.sendThemeRequest(makeThemeFileName("article"), a)
}
func (t *ThemeEngine) ThemePage(p *Page) string {
return t.sendThemeRequest(makeThemeFileName("page"), p)
}
func (t *ThemeEngine) ThemeList(content string, prev, next int) string {
data := map[string]interface{}{"content": content}
if prev > 0 {
data["prev"] = prev
}
if next > 0 {
data["next"] = next
}
return t.sendThemeRequest(makeThemeFileName("list"), data)
}
func (t *ThemeEngine) Theme(content string) string {
return t.sendThemeRequest(makeThemeFileName("layout"), map[string]interface{}{"content": content})
}
func (t *ThemeEngine) loadTemplate(name string) {
tmpl, err := mustache.ParseFile(name)
if err != nil {
return
}
t.templates[name] = tmpl
}
func (t *ThemeEngine) sendThemeRequest(tmpl string, data interface{}) string {
t.request <- ThemeRequest{tmpl, data}
return <-t.response
}
func (t *ThemeEngine) Run() {
go func() {
for {
select {
case tr := <-t.request:
if tmpl, ok := t.templates[tr.template]; ok {
t.response <- tmpl.Render(tr.data)
} else {
t.response <- ""
}
case ev := <-t.watcher.Event:
//filter for just template files
//see comment on line 39
log.Print(ev)
if (ev.IsModify() || ev.IsRename()) && strings.HasSuffix(ev.Name, ".tmpl.html") {
t.loadTemplate(ev.Name)
}
case err := <-t.watcher.Error:
log.Print("Error in file watcher:", err)
}
}
}()
}