doc.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // Copyright 2012 The Gorilla Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. /*
  5. Package gorilla/schema fills a struct with form values.
  6. The basic usage is really simple. Given this struct:
  7. type Person struct {
  8. Name string
  9. Phone string
  10. }
  11. ...we can fill it passing a map to the Decode() function:
  12. values := map[string][]string{
  13. "Name": {"John"},
  14. "Phone": {"999-999-999"},
  15. }
  16. person := new(Person)
  17. decoder := schema.NewDecoder()
  18. decoder.Decode(person, values)
  19. This is just a simple example and it doesn't make a lot of sense to create
  20. the map manually. Typically it will come from a http.Request object and
  21. will be of type url.Values, http.Request.Form, or http.Request.MultipartForm:
  22. func MyHandler(w http.ResponseWriter, r *http.Request) {
  23. err := r.ParseForm()
  24. if err != nil {
  25. // Handle error
  26. }
  27. decoder := schema.NewDecoder()
  28. // r.PostForm is a map of our POST form values
  29. err := decoder.Decode(person, r.PostForm)
  30. if err != nil {
  31. // Handle error
  32. }
  33. // Do something with person.Name or person.Phone
  34. }
  35. Note: it is a good idea to set a Decoder instance as a package global,
  36. because it caches meta-data about structs, and an instance can be shared safely:
  37. var decoder = schema.NewDecoder()
  38. To define custom names for fields, use a struct tag "schema". To not populate
  39. certain fields, use a dash for the name and it will be ignored:
  40. type Person struct {
  41. Name string `schema:"name"` // custom name
  42. Phone string `schema:"phone"` // custom name
  43. Admin bool `schema:"-"` // this field is never set
  44. }
  45. The supported field types in the destination struct are:
  46. - bool
  47. - float variants (float32, float64)
  48. - int variants (int, int8, int16, int32, int64)
  49. - string
  50. - uint variants (uint, uint8, uint16, uint32, uint64)
  51. - struct
  52. - a pointer to one of the above types
  53. - a slice or a pointer to a slice of one of the above types
  54. Non-supported types are simply ignored, however custom types can be registered
  55. to be converted.
  56. To fill nested structs, keys must use a dotted notation as the "path" for the
  57. field. So for example, to fill the struct Person below:
  58. type Phone struct {
  59. Label string
  60. Number string
  61. }
  62. type Person struct {
  63. Name string
  64. Phone Phone
  65. }
  66. ...the source map must have the keys "Name", "Phone.Label" and "Phone.Number".
  67. This means that an HTML form to fill a Person struct must look like this:
  68. <form>
  69. <input type="text" name="Name">
  70. <input type="text" name="Phone.Label">
  71. <input type="text" name="Phone.Number">
  72. </form>
  73. Single values are filled using the first value for a key from the source map.
  74. Slices are filled using all values for a key from the source map. So to fill
  75. a Person with multiple Phone values, like:
  76. type Person struct {
  77. Name string
  78. Phones []Phone
  79. }
  80. ...an HTML form that accepts three Phone values would look like this:
  81. <form>
  82. <input type="text" name="Name">
  83. <input type="text" name="Phones.0.Label">
  84. <input type="text" name="Phones.0.Number">
  85. <input type="text" name="Phones.1.Label">
  86. <input type="text" name="Phones.1.Number">
  87. <input type="text" name="Phones.2.Label">
  88. <input type="text" name="Phones.2.Number">
  89. </form>
  90. Notice that only for slices of structs the slice index is required.
  91. This is needed for disambiguation: if the nested struct also had a slice
  92. field, we could not translate multiple values to it if we did not use an
  93. index for the parent struct.
  94. There's also the possibility to create a custom type that implements the
  95. TextUnmarshaler interface, and in this case there's no need to register
  96. a converter, like:
  97. type Person struct {
  98. Emails []Email
  99. }
  100. type Email struct {
  101. *mail.Address
  102. }
  103. func (e *Email) UnmarshalText(text []byte) (err error) {
  104. e.Address, err = mail.ParseAddress(string(text))
  105. return
  106. }
  107. ...an HTML form that accepts three Email values would look like this:
  108. <form>
  109. <input type="email" name="Emails.0">
  110. <input type="email" name="Emails.1">
  111. <input type="email" name="Emails.2">
  112. </form>
  113. */
  114. package schema