Skip to content

How can I translate fieldName? #364

Closed
@syssam

Description

@syssam

How can I translate fieldName?

Activity

deankarn

deankarn commented on May 14, 2018

@deankarn
Contributor

Hey, @syssam to do this you'll have to register your own translations and either reference an external object to translate, like a map or use the translator already being used; below is an example of the latter.

package main

import (
	"fmt"

	"github.com/go-playground/locales/en_US"
	"github.com/go-playground/locales/fr_CA"
	"github.com/go-playground/universal-translator"
	"gopkg.in/go-playground/validator.v9"
)

func main() {
	english := en_US.New()

	trans := ut.New(english, english, fr_CA.New())

	en, _ := trans.GetTranslator("en")
	en.Add("MyField", "Field", false)

	fr, _ := trans.GetTranslator("fr_CA")
	fr.Add("MyField", "Champ", false)

	validate := validator.New()
	validate.RegisterTranslation("required", en,
		func(ut ut.Translator) error {
			return ut.Add("required", "{0} is required", false)
		},
		func(ut ut.Translator, fe validator.FieldError) string {
			fld, _ := ut.T(fe.Field())
			t, err := ut.T(fe.Tag(), fld)
			if err != nil {
				return fe.(error).Error()
			}
			return t
		},
	)
	validate.RegisterTranslation("required", fr,
		func(ut ut.Translator) error {
			return ut.Add("required", "{0} est requis", false)
		},
		func(ut ut.Translator, fe validator.FieldError) string {
			fld, _ := ut.T(fe.Field())
			t, err := ut.T(fe.Tag(), fld)
			if err != nil {
				return fe.(error).Error()
			}
			return t
		},
	)

	s := struct {
		MyField *string `validate:"required"`
	}{}
	errs := validate.Struct(s)

	fmt.Println(errs.(validator.ValidationErrors)[0].Translate(en))
	fmt.Println(errs.(validator.ValidationErrors)[0].Translate(fr))
}

let me know if you have any questions.

self-assigned this
on May 14, 2018
syssam

syssam commented on May 14, 2018

@syssam
Author

But I am using gopkg.in/go-playground/validator.v9/translations/en",
This case will be replace it?

syssam

syssam commented on May 14, 2018

@syssam
Author

According my current understanding, I can using RegisterTagNameFunc to translations the field name, but it will be cause the json key also translated.
Is my usage wrong?

deankarn

deankarn commented on May 14, 2018

@deankarn
Contributor

although RegisterTagNameFunc could technically be used to affect the translation, that's not what it was designed for; it's more for being able to pass error information back to a caller, such as and HTTP API and used client side.

for example, if you were using this library in an HTTP API the field name could be used as the name of the test field which the javascript need to set an error in.

I'm sure there are many other uses also.

if you register your own translations, yes you can override the ones in gopkg.in/go-playground/validator.v9/translations/en, you just have to set the override flag to true, but if you're going to replace all of them I'd just copy-paste-modify the translations file into your own library/code/repo and. use it with whatever translations you require.

unfortunately to achieve this, there is a little work required, but there's just no way I can make a single set of translations work for everyone's use case, the ones provided are just a general set and why you can register your own for your use case :)

This is also the first attempt at integrating translations into this library and I'm still gethering data on how people use them; I know it doesn't help now, but I intend to make it much easier to use translation in the next version.

syssam

syssam commented on May 15, 2018

@syssam
Author

um, I have an idea, load a json file, like lang/en/validation.json
Struct below

{
    "required": "The :attribute field is required.",
    "len": {
        "numeric" : "The :attribute must be :size.",
        "file"    : "The :attribute must be :size kilobytes.",
        "string"  : "The :attribute must be :size characters.",
        "array"   : "The :attribute must contain :size items."
    },
    "custom" : {
        "User.FirstName" : {
            "required" : "custom-message"
        }
    },
    "attributes": {
        "first_name"	: "First Name",
        "last_name"	: "Last Name"
    }
}

The validator default will be load en, provide a function load another lang.
The user can be easy to change the custom message, and more clearly.
change Json content is easier then add or change validator function.
Because the json only will be load one time on the validataion Init, so I think the performance will not be afftect.

deankarn

deankarn commented on May 16, 2018

@deankarn
Contributor

@syssam it's not a bad idea, just not a direction I want to take the validation library in, I think this functionality should remain in the realm of the translator/translation engine.

for example universal-translator already provides similar functionality and handles l10n, which the above example does not account for.

by no means does anyone have to use the translation logic that's built in, it's just a convenience for the majority, anyone can use FieldError, which contains almost all information anyone would need, to perform translations as they need.

syssam

syssam commented on May 16, 2018

@syssam
Author

Yes, I know universal-translator already provides similar functionality.

Sometimes, we need translation from other people, but we do not send a "golang" file, because the translator do not know the program. JSON format is more common and easily to tell the translator how to do it.

On the other hand, useris more easily to understand and custom own error message and more normally.I saw many framework i18n also like this.

I know you want this package is focus on the validation and user write a golang to translations as they need.

But I think more user are hoping you can provide a simple translation with validation and default different language package.

It can reduce the user a lot of time.

vuon9

vuon9 commented on Jun 13, 2019

@vuon9
Contributor

Hello!
In case I use validator with Gin framework, it always returns the validation errors with struct name. How can I remove it? Like the Person in this one:

type Person struct {
   Name string `json:"name" validate:"required"`
   Age int `json:"age" validate:"required,numeric,gte=1"`
}

Actual:

{
  "Person.name": "The name field is required",
  "Person.age": "The age field is required"
}

Expectation:

{
  "name": "The name field is required",
  "age": "The age field is required"
}

Thanks.

shaodahong

shaodahong commented on Jun 14, 2019

@shaodahong

like

type Person struct {
   Name string `json:"name" validate:"required" trans:"people name"`
   Age int `json:"age" validate:"required,numeric,gte=1" trans:"people age"`
}
{
  "name": "The people name is required",
  "age": "The people age is required"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @vuon9@deankarn@shaodahong@syssam

      Issue actions

        How can I translate fieldName? · Issue #364 · go-playground/validator