11 "github.com/go-playground/locales"
12 ut "github.com/go-playground/universal-translator"
13 "gopkg.in/go-playground/validator.v9"
16 // RegisterDefaultTranslations registers a set of default translations
17 // for all built in tag's in validator; you may add your own as desired.
18 func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (err error) {
20 translations := []struct {
24 customRegisFunc validator.RegisterTranslationsFunc
25 customTransFunc validator.TranslationFunc
29 translation: "{0} is a required field",
34 customRegisFunc: func(ut ut.Translator) (err error) {
36 if err = ut.Add("len-string", "{0} must be {1} in length", false); err != nil {
40 if err = ut.AddCardinal("len-string-character", "{0} character", locales.PluralRuleOne, false); err != nil {
44 if err = ut.AddCardinal("len-string-character", "{0} characters", locales.PluralRuleOther, false); err != nil {
48 if err = ut.Add("len-number", "{0} must be equal to {1}", false); err != nil {
52 if err = ut.Add("len-items", "{0} must contain {1}", false); err != nil {
55 if err = ut.AddCardinal("len-items-item", "{0} item", locales.PluralRuleOne, false); err != nil {
59 if err = ut.AddCardinal("len-items-item", "{0} items", locales.PluralRuleOther, false); err != nil {
66 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
73 if idx := strings.Index(fe.Param(), "."); idx != -1 {
74 digits = uint64(len(fe.Param()[idx+1:]))
77 f64, err := strconv.ParseFloat(fe.Param(), 64)
87 c, err = ut.C("len-string-character", f64, digits, ut.FmtNumber(f64, digits))
92 t, err = ut.T("len-string", fe.Field(), c)
94 case reflect.Slice, reflect.Map, reflect.Array:
97 c, err = ut.C("len-items-item", f64, digits, ut.FmtNumber(f64, digits))
102 t, err = ut.T("len-items", fe.Field(), c)
105 t, err = ut.T("len-number", fe.Field(), ut.FmtNumber(f64, digits))
110 fmt.Printf("warning: error translating FieldError: %s", err)
111 return fe.(error).Error()
119 customRegisFunc: func(ut ut.Translator) (err error) {
121 if err = ut.Add("min-string", "{0} must be at least {1} in length", false); err != nil {
125 if err = ut.AddCardinal("min-string-character", "{0} character", locales.PluralRuleOne, false); err != nil {
129 if err = ut.AddCardinal("min-string-character", "{0} characters", locales.PluralRuleOther, false); err != nil {
133 if err = ut.Add("min-number", "{0} must be {1} or greater", false); err != nil {
137 if err = ut.Add("min-items", "{0} must contain at least {1}", false); err != nil {
140 if err = ut.AddCardinal("min-items-item", "{0} item", locales.PluralRuleOne, false); err != nil {
144 if err = ut.AddCardinal("min-items-item", "{0} items", locales.PluralRuleOther, false); err != nil {
151 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
158 if idx := strings.Index(fe.Param(), "."); idx != -1 {
159 digits = uint64(len(fe.Param()[idx+1:]))
162 f64, err := strconv.ParseFloat(fe.Param(), 64)
172 c, err = ut.C("min-string-character", f64, digits, ut.FmtNumber(f64, digits))
177 t, err = ut.T("min-string", fe.Field(), c)
179 case reflect.Slice, reflect.Map, reflect.Array:
182 c, err = ut.C("min-items-item", f64, digits, ut.FmtNumber(f64, digits))
187 t, err = ut.T("min-items", fe.Field(), c)
190 t, err = ut.T("min-number", fe.Field(), ut.FmtNumber(f64, digits))
195 fmt.Printf("warning: error translating FieldError: %s", err)
196 return fe.(error).Error()
204 customRegisFunc: func(ut ut.Translator) (err error) {
206 if err = ut.Add("max-string", "{0} must be a maximum of {1} in length", false); err != nil {
210 if err = ut.AddCardinal("max-string-character", "{0} character", locales.PluralRuleOne, false); err != nil {
214 if err = ut.AddCardinal("max-string-character", "{0} characters", locales.PluralRuleOther, false); err != nil {
218 if err = ut.Add("max-number", "{0} must be {1} or less", false); err != nil {
222 if err = ut.Add("max-items", "{0} must contain at maximum {1}", false); err != nil {
225 if err = ut.AddCardinal("max-items-item", "{0} item", locales.PluralRuleOne, false); err != nil {
229 if err = ut.AddCardinal("max-items-item", "{0} items", locales.PluralRuleOther, false); err != nil {
236 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
243 if idx := strings.Index(fe.Param(), "."); idx != -1 {
244 digits = uint64(len(fe.Param()[idx+1:]))
247 f64, err := strconv.ParseFloat(fe.Param(), 64)
257 c, err = ut.C("max-string-character", f64, digits, ut.FmtNumber(f64, digits))
262 t, err = ut.T("max-string", fe.Field(), c)
264 case reflect.Slice, reflect.Map, reflect.Array:
267 c, err = ut.C("max-items-item", f64, digits, ut.FmtNumber(f64, digits))
272 t, err = ut.T("max-items", fe.Field(), c)
275 t, err = ut.T("max-number", fe.Field(), ut.FmtNumber(f64, digits))
280 fmt.Printf("warning: error translating FieldError: %s", err)
281 return fe.(error).Error()
289 translation: "{0} is not equal to {1}",
291 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
293 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
295 fmt.Printf("warning: error translating FieldError: %#v", fe)
296 return fe.(error).Error()
304 translation: "{0} should not be equal to {1}",
306 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
308 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
310 fmt.Printf("warning: error translating FieldError: %#v", fe)
311 return fe.(error).Error()
319 customRegisFunc: func(ut ut.Translator) (err error) {
321 if err = ut.Add("lt-string", "{0} must be less than {1} in length", false); err != nil {
325 if err = ut.AddCardinal("lt-string-character", "{0} character", locales.PluralRuleOne, false); err != nil {
329 if err = ut.AddCardinal("lt-string-character", "{0} characters", locales.PluralRuleOther, false); err != nil {
333 if err = ut.Add("lt-number", "{0} must be less than {1}", false); err != nil {
337 if err = ut.Add("lt-items", "{0} must contain less than {1}", false); err != nil {
341 if err = ut.AddCardinal("lt-items-item", "{0} item", locales.PluralRuleOne, false); err != nil {
345 if err = ut.AddCardinal("lt-items-item", "{0} items", locales.PluralRuleOther, false); err != nil {
349 if err = ut.Add("lt-datetime", "{0} must be less than the current Date & Time", false); err != nil {
356 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
363 fn := func() (err error) {
365 if idx := strings.Index(fe.Param(), "."); idx != -1 {
366 digits = uint64(len(fe.Param()[idx+1:]))
369 f64, err = strconv.ParseFloat(fe.Param(), 64)
384 c, err = ut.C("lt-string-character", f64, digits, ut.FmtNumber(f64, digits))
389 t, err = ut.T("lt-string", fe.Field(), c)
391 case reflect.Slice, reflect.Map, reflect.Array:
399 c, err = ut.C("lt-items-item", f64, digits, ut.FmtNumber(f64, digits))
404 t, err = ut.T("lt-items", fe.Field(), c)
407 if fe.Type() != reflect.TypeOf(time.Time{}) {
408 err = fmt.Errorf("tag '%s' cannot be used on a struct type.", fe.Tag())
411 t, err = ut.T("lt-datetime", fe.Field())
419 t, err = ut.T("lt-number", fe.Field(), ut.FmtNumber(f64, digits))
424 fmt.Printf("warning: error translating FieldError: %s", err)
425 return fe.(error).Error()
433 customRegisFunc: func(ut ut.Translator) (err error) {
435 if err = ut.Add("lte-string", "{0} must be at maximum {1} in length", false); err != nil {
439 if err = ut.AddCardinal("lte-string-character", "{0} character", locales.PluralRuleOne, false); err != nil {
443 if err = ut.AddCardinal("lte-string-character", "{0} characters", locales.PluralRuleOther, false); err != nil {
447 if err = ut.Add("lte-number", "{0} must be {1} or less", false); err != nil {
451 if err = ut.Add("lte-items", "{0} must contain at maximum {1}", false); err != nil {
455 if err = ut.AddCardinal("lte-items-item", "{0} item", locales.PluralRuleOne, false); err != nil {
459 if err = ut.AddCardinal("lte-items-item", "{0} items", locales.PluralRuleOther, false); err != nil {
463 if err = ut.Add("lte-datetime", "{0} must be less than or equal to the current Date & Time", false); err != nil {
469 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
476 fn := func() (err error) {
478 if idx := strings.Index(fe.Param(), "."); idx != -1 {
479 digits = uint64(len(fe.Param()[idx+1:]))
482 f64, err = strconv.ParseFloat(fe.Param(), 64)
497 c, err = ut.C("lte-string-character", f64, digits, ut.FmtNumber(f64, digits))
502 t, err = ut.T("lte-string", fe.Field(), c)
504 case reflect.Slice, reflect.Map, reflect.Array:
512 c, err = ut.C("lte-items-item", f64, digits, ut.FmtNumber(f64, digits))
517 t, err = ut.T("lte-items", fe.Field(), c)
520 if fe.Type() != reflect.TypeOf(time.Time{}) {
521 err = fmt.Errorf("tag '%s' cannot be used on a struct type.", fe.Tag())
524 t, err = ut.T("lte-datetime", fe.Field())
532 t, err = ut.T("lte-number", fe.Field(), ut.FmtNumber(f64, digits))
537 fmt.Printf("warning: error translating FieldError: %s", err)
538 return fe.(error).Error()
546 customRegisFunc: func(ut ut.Translator) (err error) {
548 if err = ut.Add("gt-string", "{0} must be greater than {1} in length", false); err != nil {
552 if err = ut.AddCardinal("gt-string-character", "{0} character", locales.PluralRuleOne, false); err != nil {
556 if err = ut.AddCardinal("gt-string-character", "{0} characters", locales.PluralRuleOther, false); err != nil {
560 if err = ut.Add("gt-number", "{0} must be greater than {1}", false); err != nil {
564 if err = ut.Add("gt-items", "{0} must contain more than {1}", false); err != nil {
568 if err = ut.AddCardinal("gt-items-item", "{0} item", locales.PluralRuleOne, false); err != nil {
572 if err = ut.AddCardinal("gt-items-item", "{0} items", locales.PluralRuleOther, false); err != nil {
576 if err = ut.Add("gt-datetime", "{0} must be greater than the current Date & Time", false); err != nil {
582 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
589 fn := func() (err error) {
591 if idx := strings.Index(fe.Param(), "."); idx != -1 {
592 digits = uint64(len(fe.Param()[idx+1:]))
595 f64, err = strconv.ParseFloat(fe.Param(), 64)
610 c, err = ut.C("gt-string-character", f64, digits, ut.FmtNumber(f64, digits))
615 t, err = ut.T("gt-string", fe.Field(), c)
617 case reflect.Slice, reflect.Map, reflect.Array:
625 c, err = ut.C("gt-items-item", f64, digits, ut.FmtNumber(f64, digits))
630 t, err = ut.T("gt-items", fe.Field(), c)
633 if fe.Type() != reflect.TypeOf(time.Time{}) {
634 err = fmt.Errorf("tag '%s' cannot be used on a struct type.", fe.Tag())
637 t, err = ut.T("gt-datetime", fe.Field())
645 t, err = ut.T("gt-number", fe.Field(), ut.FmtNumber(f64, digits))
650 fmt.Printf("warning: error translating FieldError: %s", err)
651 return fe.(error).Error()
659 customRegisFunc: func(ut ut.Translator) (err error) {
661 if err = ut.Add("gte-string", "{0} must be at least {1} in length", false); err != nil {
665 if err = ut.AddCardinal("gte-string-character", "{0} character", locales.PluralRuleOne, false); err != nil {
669 if err = ut.AddCardinal("gte-string-character", "{0} characters", locales.PluralRuleOther, false); err != nil {
673 if err = ut.Add("gte-number", "{0} must be {1} or greater", false); err != nil {
677 if err = ut.Add("gte-items", "{0} must contain at least {1}", false); err != nil {
681 if err = ut.AddCardinal("gte-items-item", "{0} item", locales.PluralRuleOne, false); err != nil {
685 if err = ut.AddCardinal("gte-items-item", "{0} items", locales.PluralRuleOther, false); err != nil {
689 if err = ut.Add("gte-datetime", "{0} must be greater than or equal to the current Date & Time", false); err != nil {
695 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
702 fn := func() (err error) {
704 if idx := strings.Index(fe.Param(), "."); idx != -1 {
705 digits = uint64(len(fe.Param()[idx+1:]))
708 f64, err = strconv.ParseFloat(fe.Param(), 64)
723 c, err = ut.C("gte-string-character", f64, digits, ut.FmtNumber(f64, digits))
728 t, err = ut.T("gte-string", fe.Field(), c)
730 case reflect.Slice, reflect.Map, reflect.Array:
738 c, err = ut.C("gte-items-item", f64, digits, ut.FmtNumber(f64, digits))
743 t, err = ut.T("gte-items", fe.Field(), c)
746 if fe.Type() != reflect.TypeOf(time.Time{}) {
747 err = fmt.Errorf("tag '%s' cannot be used on a struct type.", fe.Tag())
750 t, err = ut.T("gte-datetime", fe.Field())
758 t, err = ut.T("gte-number", fe.Field(), ut.FmtNumber(f64, digits))
763 fmt.Printf("warning: error translating FieldError: %s", err)
764 return fe.(error).Error()
772 translation: "{0} must be equal to {1}",
774 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
776 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
778 log.Printf("warning: error translating FieldError: %#v", fe)
779 return fe.(error).Error()
787 translation: "{0} must be equal to {1}",
789 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
791 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
793 log.Printf("warning: error translating FieldError: %#v", fe)
794 return fe.(error).Error()
802 translation: "{0} cannot be equal to {1}",
804 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
806 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
808 log.Printf("warning: error translating FieldError: %#v", fe)
809 return fe.(error).Error()
817 translation: "{0} must be greater than {1}",
819 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
821 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
823 log.Printf("warning: error translating FieldError: %#v", fe)
824 return fe.(error).Error()
832 translation: "{0} must be greater than or equal to {1}",
834 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
836 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
838 log.Printf("warning: error translating FieldError: %#v", fe)
839 return fe.(error).Error()
847 translation: "{0} must be less than {1}",
849 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
851 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
853 log.Printf("warning: error translating FieldError: %#v", fe)
854 return fe.(error).Error()
862 translation: "{0} must be less than or equal to {1}",
864 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
866 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
868 log.Printf("warning: error translating FieldError: %#v", fe)
869 return fe.(error).Error()
877 translation: "{0} cannot be equal to {1}",
879 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
881 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
883 log.Printf("warning: error translating FieldError: %#v", fe)
884 return fe.(error).Error()
892 translation: "{0} must be greater than {1}",
894 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
896 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
898 log.Printf("warning: error translating FieldError: %#v", fe)
899 return fe.(error).Error()
907 translation: "{0} must be greater than or equal to {1}",
909 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
911 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
913 log.Printf("warning: error translating FieldError: %#v", fe)
914 return fe.(error).Error()
922 translation: "{0} must be less than {1}",
924 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
926 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
928 log.Printf("warning: error translating FieldError: %#v", fe)
929 return fe.(error).Error()
937 translation: "{0} must be less than or equal to {1}",
939 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
941 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
943 log.Printf("warning: error translating FieldError: %#v", fe)
944 return fe.(error).Error()
952 translation: "{0} can only contain alphabetic characters",
957 translation: "{0} can only contain alphanumeric characters",
962 translation: "{0} must be a valid numeric value",
967 translation: "{0} must be a valid number",
972 translation: "{0} must be a valid hexadecimal",
977 translation: "{0} must be a valid HEX color",
982 translation: "{0} must be a valid RGB color",
987 translation: "{0} must be a valid RGBA color",
992 translation: "{0} must be a valid HSL color",
997 translation: "{0} must be a valid HSLA color",
1002 translation: "{0} must be a valid email address",
1007 translation: "{0} must be a valid URL",
1012 translation: "{0} must be a valid URI",
1017 translation: "{0} must be a valid Base64 string",
1022 translation: "{0} must contain the text '{1}'",
1024 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1026 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
1028 log.Printf("warning: error translating FieldError: %#v", fe)
1029 return fe.(error).Error()
1037 translation: "{0} must contain at least one of the following characters '{1}'",
1039 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1041 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
1043 log.Printf("warning: error translating FieldError: %#v", fe)
1044 return fe.(error).Error()
1052 translation: "{0} cannot contain the text '{1}'",
1054 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1056 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
1058 log.Printf("warning: error translating FieldError: %#v", fe)
1059 return fe.(error).Error()
1067 translation: "{0} cannot contain any of the following characters '{1}'",
1069 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1071 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
1073 log.Printf("warning: error translating FieldError: %#v", fe)
1074 return fe.(error).Error()
1081 tag: "excludesrune",
1082 translation: "{0} cannot contain the following '{1}'",
1084 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1086 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
1088 log.Printf("warning: error translating FieldError: %#v", fe)
1089 return fe.(error).Error()
1097 translation: "{0} must be a valid ISBN number",
1102 translation: "{0} must be a valid ISBN-10 number",
1107 translation: "{0} must be a valid ISBN-13 number",
1112 translation: "{0} must be a valid UUID",
1117 translation: "{0} must be a valid version 3 UUID",
1122 translation: "{0} must be a valid version 4 UUID",
1127 translation: "{0} must be a valid version 5 UUID",
1132 translation: "{0} must contain only ascii characters",
1137 translation: "{0} must contain only printable ascii characters",
1142 translation: "{0} must contain multibyte characters",
1147 translation: "{0} must contain a valid Data URI",
1152 translation: "{0} must contain valid latitude coordinates",
1157 translation: "{0} must contain a valid longitude coordinates",
1162 translation: "{0} must be a valid SSN number",
1167 translation: "{0} must be a valid IPv4 address",
1172 translation: "{0} must be a valid IPv6 address",
1177 translation: "{0} must be a valid IP address",
1182 translation: "{0} must contain a valid CIDR notation",
1187 translation: "{0} must contain a valid CIDR notation for an IPv4 address",
1192 translation: "{0} must contain a valid CIDR notation for an IPv6 address",
1197 translation: "{0} must be a valid TCP address",
1202 translation: "{0} must be a valid IPv4 TCP address",
1207 translation: "{0} must be a valid IPv6 TCP address",
1212 translation: "{0} must be a valid UDP address",
1217 translation: "{0} must be a valid IPv4 UDP address",
1222 translation: "{0} must be a valid IPv6 UDP address",
1227 translation: "{0} must be a resolvable IP address",
1232 translation: "{0} must be a resolvable IPv4 address",
1237 translation: "{0} must be a resolvable IPv6 address",
1242 translation: "{0} must be a resolvable UNIX address",
1247 translation: "{0} must contain a valid MAC address",
1252 translation: "{0} must be a valid color",
1257 for _, t := range translations {
1259 if t.customTransFunc != nil && t.customRegisFunc != nil {
1261 err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, t.customTransFunc)
1263 } else if t.customTransFunc != nil && t.customRegisFunc == nil {
1265 err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), t.customTransFunc)
1267 } else if t.customTransFunc == nil && t.customRegisFunc != nil {
1269 err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, translateFunc)
1272 err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), translateFunc)
1283 func registrationFunc(tag string, translation string, override bool) validator.RegisterTranslationsFunc {
1285 return func(ut ut.Translator) (err error) {
1287 if err = ut.Add(tag, translation, override); err != nil {
1297 func translateFunc(ut ut.Translator, fe validator.FieldError) string {
1299 t, err := ut.T(fe.Tag(), fe.Field())
1301 log.Printf("warning: error translating FieldError: %#v", fe)
1302 return fe.(error).Error()