-
Notifications
You must be signed in to change notification settings - Fork 0
/
pages.go
99 lines (86 loc) · 2.49 KB
/
pages.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
package uos
import (
"bytes"
"fmt"
"html/template"
"net/http"
)
// PageHandler returns a standard GET handler for a template based page.
//
// Called with a single parameter: specifiy the page template name, will be provided at "/<name>".
//
// Calles with two parameters: specify route and page name.
//
// Panics if no or more than two parameters are provided. The returned handler can be activated
// using RegisterAppRequestHandlers.
func PageHandler(page ...string) AppRequestHandlerMapping {
if len(page) == 0 || len(page) > 2 {
panic("PageHandler must be called with one or two parameters.")
}
var route, name string
if len(page) == 1 {
route = fmt.Sprintf("/%s", page[0])
name = page[0]
} else {
route = page[0]
name = page[1]
}
return AppRequestHandlerMapping{
Route: route,
Handler: func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet || r.URL.Path != route {
RespondNotFound(w)
return
}
renderPage(
w, r, name,
map[string]interface{}{
"Object": r.Form.Get("p"),
},
)
},
}
}
type PageConfigurationHandler func(string, *http.Request, *PageConfiguration)
var pageConfigCB = func(string, *http.Request, *PageConfiguration) {
Log.Trace("default page configuration handler")
}
func RegisterPageConfigurationHook(cb PageConfigurationHandler) {
pageConfigCB = cb
}
// renderPage loads the base page template and the content template with the specified name
// and writes the combined result to the specified writer using the given data context.
func renderPage(w http.ResponseWriter, r *http.Request, name string, data map[string]interface{}) {
pageTemplateName := "page_" + name
// render page content
var content bytes.Buffer
err := renderTemplate(&content, r, name, data, pageTemplateName)
if err != nil {
Log.ErrorContextR(
r, "could not render page content template",
LogContext{"name": name, "error": err},
)
RespondInternalServerError(w)
return
}
// integrate content in base page
if data == nil {
data = map[string]interface{}{}
}
// .. content
data["Content"] = template.HTML(content.String())
// .. base configuration (title, scripts, styles, ...)
pageConfig := Config.getPageConfig(name)
pageConfigCB(name, r, &pageConfig)
data["Page"] = pageConfig
data["Features"] = Config.Features
err = renderInternalTemplate(w, r, "page", data)
if err != nil {
Log.ErrorContextR(
r, "could not render page",
LogContext{"name": name, "error": err},
)
RespondInternalServerError(w)
return
}
}