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  }