forked from volatiletech/authboss
-
Notifications
You must be signed in to change notification settings - Fork 0
/
html_data.go
107 lines (92 loc) · 3.09 KB
/
html_data.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
package authboss
import (
"context"
"net/http"
)
// Keys for use in HTMLData that are meaningful
const (
// DataErr is for one off errors that don't really belong to
// a particular field. It should be a string.
DataErr = "error"
// DataValidation is for validation errors, it should always
// have been created using the Map() style functions in the
// validation method so that html/text template users don't
// struggle in displaying them.
//
// It is: map[string][]string, where the key in the map is the field
// and the []string on the other side is the list of problems
// with that field.
//
// It's also important to note that if the errors that were Map()'d
// did not implement FieldError or for generic errors
// the empty string ("") is used as a key in the map for those
// errors that couldn't be fit to a specific field.
DataValidation = "errors"
// DataPreserve preserves fields during large form exercises
// like user registration so we don't have to re-type safe
// information like addresses etc.
//
// This data looks like map[string]string, and is simply
// keyed by the field name, and the value is the field value.
DataPreserve = "preserve"
// DataModules contains a map[string]bool of which modules are loaded
// The bool is largely extraneous and can be ignored, if the module is
// loaded it will be present in the map, if not it will be missing.
DataModules = "modules"
)
// HTMLData is used to render templates with.
type HTMLData map[string]interface{}
// NewHTMLData creates HTMLData from key-value pairs. The input is a key-value
// slice, where odd elements are keys, and the following even element
// is their value.
func NewHTMLData(data ...interface{}) HTMLData {
if len(data)%2 != 0 {
panic("it should be a key value list of arguments.")
}
h := make(HTMLData)
for i := 0; i < len(data)-1; i += 2 {
k, ok := data[i].(string)
if !ok {
panic("Keys must be strings.")
}
h[k] = data[i+1]
}
return h
}
// Merge adds the data from other to h. If there are conflicting keys
// they are overwritten by other's values.
func (h HTMLData) Merge(other HTMLData) HTMLData {
for k, v := range other {
h[k] = v
}
return h
}
// MergeKV adds extra key-values to the HTMLData. The input is a key-value
// slice, where odd elements are keys, and the following even element
// is their value.
func (h HTMLData) MergeKV(data ...interface{}) HTMLData {
if len(data)%2 != 0 {
panic("It should be a key value list of arguments.")
}
for i := 0; i < len(data)-1; i += 2 {
k, ok := data[i].(string)
if !ok {
panic("Keys must be strings.")
}
h[k] = data[i+1]
}
return h
}
// MergeDataInRequest edits the request pointer to point to a new request with
// a modified context that contains the merged data.
func MergeDataInRequest(r **http.Request, other HTMLData) {
ctx := (*r).Context()
currentIntf := ctx.Value(CTXKeyData)
if currentIntf == nil {
*r = (*r).WithContext(context.WithValue(ctx, CTXKeyData, other))
return
}
current := currentIntf.(HTMLData)
merged := current.Merge(other)
*r = (*r).WithContext(context.WithValue(ctx, CTXKeyData, merged))
}