main.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/go-playground/locales/en"
  5. ut "github.com/go-playground/universal-translator"
  6. "gopkg.in/go-playground/validator.v9"
  7. en_translations "gopkg.in/go-playground/validator.v9/translations/en"
  8. )
  9. // User contains user information
  10. type User struct {
  11. FirstName string `validate:"required"`
  12. LastName string `validate:"required"`
  13. Age uint8 `validate:"gte=0,lte=130"`
  14. Email string `validate:"required,email"`
  15. FavouriteColor string `validate:"iscolor"` // alias for 'hexcolor|rgb|rgba|hsl|hsla'
  16. Addresses []*Address `validate:"required,dive,required"` // a person can have a home and cottage...
  17. }
  18. // Address houses a users address information
  19. type Address struct {
  20. Street string `validate:"required"`
  21. City string `validate:"required"`
  22. Planet string `validate:"required"`
  23. Phone string `validate:"required"`
  24. }
  25. // use a single instance , it caches struct info
  26. var (
  27. uni *ut.UniversalTranslator
  28. validate *validator.Validate
  29. )
  30. func main() {
  31. // NOTE: ommitting allot of error checking for brevity
  32. en := en.New()
  33. uni = ut.New(en, en)
  34. // this is usually know or extracted from http 'Accept-Language' header
  35. // also see uni.FindTranslator(...)
  36. trans, _ := uni.GetTranslator("en")
  37. validate = validator.New()
  38. en_translations.RegisterDefaultTranslations(validate, trans)
  39. translateAll(trans)
  40. translateIndividual(trans)
  41. translateOverride(trans) // yep you can specify your own in whatever locale you want!
  42. }
  43. func translateAll(trans ut.Translator) {
  44. type User struct {
  45. Username string `validate:"required"`
  46. Tagline string `validate:"required,lt=10"`
  47. Tagline2 string `validate:"required,gt=1"`
  48. }
  49. user := User{
  50. Username: "Joeybloggs",
  51. Tagline: "This tagline is way too long.",
  52. Tagline2: "1",
  53. }
  54. err := validate.Struct(user)
  55. if err != nil {
  56. // translate all error at once
  57. errs := err.(validator.ValidationErrors)
  58. // returns a map with key = namespace & value = translated error
  59. // NOTICE: 2 errors are returned and you'll see something surprising
  60. // translations are i18n aware!!!!
  61. // eg. '10 characters' vs '1 character'
  62. fmt.Println(errs.Translate(trans))
  63. }
  64. }
  65. func translateIndividual(trans ut.Translator) {
  66. type User struct {
  67. Username string `validate:"required"`
  68. }
  69. var user User
  70. err := validate.Struct(user)
  71. if err != nil {
  72. errs := err.(validator.ValidationErrors)
  73. for _, e := range errs {
  74. // can translate each error one at a time.
  75. fmt.Println(e.Translate(trans))
  76. }
  77. }
  78. }
  79. func translateOverride(trans ut.Translator) {
  80. validate.RegisterTranslation("required", trans, func(ut ut.Translator) error {
  81. return ut.Add("required", "{0} must have a value!", true) // see universal-translator for details
  82. }, func(ut ut.Translator, fe validator.FieldError) string {
  83. t, _ := ut.T("required", fe.Field())
  84. return t
  85. })
  86. type User struct {
  87. Username string `validate:"required"`
  88. }
  89. var user User
  90. err := validate.Struct(user)
  91. if err != nil {
  92. errs := err.(validator.ValidationErrors)
  93. for _, e := range errs {
  94. // can translate each error one at a time.
  95. fmt.Println(e.Translate(trans))
  96. }
  97. }
  98. }