-
Notifications
You must be signed in to change notification settings - Fork 3
/
template.go
53 lines (44 loc) · 1.19 KB
/
template.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
package torque
import (
"net/http"
"reflect"
"text/template/parse"
"github.com/tylermmorton/tmpl"
)
type templateRenderer[T ViewModel] struct {
HasOutlet bool
template tmpl.Template[tmpl.TemplateProvider]
}
func (t templateRenderer[T]) Render(wr http.ResponseWriter, _ *http.Request, vm T) error {
return t.template.Render(wr, any(vm).(tmpl.TemplateProvider))
}
func createTemplateRenderer[T ViewModel](tp tmpl.TemplateProvider) (*templateRenderer[T], error) {
var (
r = &templateRenderer[T]{}
err error
)
r.template, err = tmpl.Compile(
tp,
tmpl.UseAnalyzers(outletAnalyzer(r)),
)
if err != nil {
return nil, err
}
return r, nil
}
const outletIdent = "outlet"
func outletAnalyzer[T ViewModel](t *templateRenderer[T]) tmpl.Analyzer {
return func(h *tmpl.AnalysisHelper) tmpl.AnalyzerFunc {
return func(val reflect.Value, node parse.Node) {
switch node := node.(type) {
case *parse.IdentifierNode:
if node.Ident == outletIdent && t.HasOutlet == true {
h.AddError(node, "outlet can only be defined once per template")
} else if node.Ident == outletIdent {
t.HasOutlet = true
h.AddFunc(outletIdent, func() string { return "{{ . }}" })
}
}
}
}
}