forked from yosssi/martini-acerender
/
render.go
79 lines (62 loc) · 1.7 KB
/
render.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
package acerender
import (
"bytes"
"html/template"
"io"
"net/http"
"strings"
"github.com/go-martini/martini"
"github.com/martini-contrib/render"
"github.com/yosssi/ace"
"github.com/yosssi/ace-proxy"
)
const defaultContentType = render.ContentHTML + "; charset=utf-8"
// Render is an interface for parsing Ace templates and redering HTML.
type Render interface {
HTML(status int, name string, v interface{}, opts *ace.Options)
}
// render represents a renderer of Ace templates.
type renderer struct {
http.ResponseWriter
req *http.Request
p *proxy.Proxy
}
// HTML parses the Ace templates and renders HTML to the response writer.
func (r *renderer) HTML(status int, name string, v interface{}, opts *ace.Options) {
var basePath, innerPath string
paths := strings.Split(name, ":")
basePath = paths[0]
if len(paths) > 1 {
innerPath = paths[1]
}
tplc, errc := r.p.Load(basePath, innerPath, opts)
var tpl *template.Template
select {
case tpl = <-tplc:
case err := <-errc:
http.Error(r, err.Error(), http.StatusInternalServerError)
return
}
buf := new(bytes.Buffer)
if err := tpl.Execute(buf, v); err != nil {
http.Error(r, err.Error(), http.StatusInternalServerError)
return
}
r.Header().Set(render.ContentType, defaultContentType)
r.WriteHeader(status)
io.Copy(r, buf)
}
// Renderer is a Martini middleware that maps a render.Render service into the Martini handler chain.
func Renderer(opts *Options) martini.Handler {
opts = initializeOptions(opts)
return func(res http.ResponseWriter, req *http.Request, c martini.Context) {
c.MapTo(
&renderer{
ResponseWriter: res,
req: req,
p: proxy.New(opts.AceOptions),
},
(*Render)(nil),
)
}
}