github.com/volatiletech/authboss@v2.4.1+incompatible/html_data.go (about) 1 package authboss 2 3 import ( 4 "context" 5 "net/http" 6 ) 7 8 // Keys for use in HTMLData that are meaningful 9 const ( 10 // DataErr is for one off errors that don't really belong to 11 // a particular field. It should be a string. 12 DataErr = "error" 13 // DataValidation is for validation errors, it should always 14 // have been created using the Map() style functions in the 15 // validation method so that html/text template users don't 16 // struggle in displaying them. 17 // 18 // It is: map[string][]string, where the key in the map is the field 19 // and the []string on the other side is the list of problems 20 // with that field. 21 // 22 // It's also important to note that if the errors that were Map()'d 23 // did not implement FieldError or for generic errors 24 // the empty string ("") is used as a key in the map for those 25 // errors that couldn't be fit to a specific field. 26 DataValidation = "errors" 27 // DataPreserve preserves fields during large form exercises 28 // like user registration so we don't have to re-type safe 29 // information like addresses etc. 30 // 31 // This data looks like map[string]string, and is simply 32 // keyed by the field name, and the value is the field value. 33 DataPreserve = "preserve" 34 // DataModules contains a map[string]bool of which modules are loaded 35 // The bool is largely extraneous and can be ignored, if the module is 36 // loaded it will be present in the map, if not it will be missing. 37 DataModules = "modules" 38 ) 39 40 // HTMLData is used to render templates with. 41 type HTMLData map[string]interface{} 42 43 // NewHTMLData creates HTMLData from key-value pairs. The input is a key-value 44 // slice, where odd elements are keys, and the following even element 45 // is their value. 46 func NewHTMLData(data ...interface{}) HTMLData { 47 if len(data)%2 != 0 { 48 panic("it should be a key value list of arguments.") 49 } 50 51 h := make(HTMLData) 52 53 for i := 0; i < len(data)-1; i += 2 { 54 k, ok := data[i].(string) 55 if !ok { 56 panic("Keys must be strings.") 57 } 58 59 h[k] = data[i+1] 60 } 61 62 return h 63 } 64 65 // Merge adds the data from other to h. If there are conflicting keys 66 // they are overwritten by other's values. 67 func (h HTMLData) Merge(other HTMLData) HTMLData { 68 for k, v := range other { 69 h[k] = v 70 } 71 return h 72 } 73 74 // MergeKV adds extra key-values to the HTMLData. The input is a key-value 75 // slice, where odd elements are keys, and the following even element 76 // is their value. 77 func (h HTMLData) MergeKV(data ...interface{}) HTMLData { 78 if len(data)%2 != 0 { 79 panic("It should be a key value list of arguments.") 80 } 81 82 for i := 0; i < len(data)-1; i += 2 { 83 k, ok := data[i].(string) 84 if !ok { 85 panic("Keys must be strings.") 86 } 87 88 h[k] = data[i+1] 89 } 90 91 return h 92 } 93 94 // MergeDataInRequest edits the request pointer to point to a new request with 95 // a modified context that contains the merged data. 96 func MergeDataInRequest(r **http.Request, other HTMLData) { 97 ctx := (*r).Context() 98 currentIntf := ctx.Value(CTXKeyData) 99 if currentIntf == nil { 100 *r = (*r).WithContext(context.WithValue(ctx, CTXKeyData, other)) 101 return 102 } 103 104 current := currentIntf.(HTMLData) 105 merged := current.Merge(other) 106 *r = (*r).WithContext(context.WithValue(ctx, CTXKeyData, merged)) 107 }