-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add translation example #1394
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add translation example #1394
Conversation
_examples/translations/main.go
Outdated
// The supported locales need to be predefined. | ||
enTrans, _ := uni.GetTranslator("en") | ||
en_translations.RegisterDefaultTranslations(validate, enTrans) | ||
zhTrans, _ := uni.GetTranslator("zh") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your contribution to the project.
Where is zhTrans
being used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your contribution to the project.
Where is
zhTrans
being used?
The variable zhTrans exists to register the global Chinese translator using zh_translations.RegisterDefaultTranslations(validate, zhTrans)
. This is done to ensure that both English (en) and Chinese (zh) can be supported in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm....
When I execute this example, the Chinese translation doesn't appear.
$ cd _examples/translations && go run main.go
map[User.Tagline:Tagline must be less than 10 characters in length User.Tagline2:Tagline2 must be greater than 1 character in length]
Username is a required field
Username must have a value!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm.... When I execute this example, the Chinese translation doesn't appear.
$ cd _examples/translations && go run main.go map[User.Tagline:Tagline must be less than 10 characters in length User.Tagline2:Tagline2 must be greater than 1 character in length] Username is a required field Username must have a value!
The purpose of en_translations.RegisterDefaultTranslations(validate, enTrans) and zh_translations.RegisterDefaultTranslations(validate, zhTrans) is to pre-register all supported languages. However, the specific language to be used is determined by the accept-language in the HTTP header. For simplicity, a fixed value (uni.GetTranslator("en")) is hardcoded in the code. Below is a demo from our real-world scenario.
package main
import (
"encoding/json"
"errors"
"github.com/go-playground/locales/en"
"github.com/go-playground/locales/zh"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
en_translations "github.com/go-playground/validator/v10/translations/en"
zh_translations "github.com/go-playground/validator/v10/translations/zh"
"net/http"
)
var uni *ut.UniversalTranslator
func main() {
validate := validator.New()
en := en.New()
uni = ut.New(en, en, zh.New())
validate = validator.New()
enTrans, _ := uni.GetTranslator("en")
en_translations.RegisterDefaultTranslations(validate, enTrans)
zhTrans, _ := uni.GetTranslator("zh")
zh_translations.RegisterDefaultTranslations(validate, zhTrans)
type User struct {
FirstName string `json:"first_name" validate:"required"`
LastName string `json:"last_name" validate:"required"`
}
http.HandleFunc("POST /users", func(w http.ResponseWriter, r *http.Request) {
// ... fill user value
var user User
// Header Accept-Language value is en or zh
trans, _ := uni.GetTranslator(r.Header.Get("Accept-Language"))
if err := validate.Struct(&user); err != nil {
var errs validator.ValidationErrors
var httpErrors []validator.ValidationErrorsTranslations
if errors.As(err, &errs) {
httpErrors = append(httpErrors, errs.Translate(trans))
}
r, _ := json.Marshal(httpErrors)
w.Write(r)
}
})
http.ListenAndServe(":8081", nil)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ☝️ type of example is highly valuable. I’d include it in this PR as a separate function, possibly with a client http request that sets the Accept-Language
header to 'zh'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried executing your example, but it resulted in the following error:
main.go:8:2: cannot find module providing package github.com/go-playground/locales/zh_Hant:
Would you be able to fix it?
Could you provide the execution environment? It works fine on my local machine. Could you also check whether the relevant packages are present?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you go:
$ git clean -ffdx
$ go mod vendor
$ cd _examples/http-transalations
$ go run main.go
main.go:8:2: cannot find module providing package github.com/go-playground/locales/zh_Hant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you go:
$ git clean -ffdx $ go mod vendor $ cd _examples/http-transalations $ go run main.go main.go:8:2: cannot find module providing package github.com/go-playground/locales/zh_Hant
I pinpointed the issue and found that the dependency related to zh_Hant wasn't included during compilation, which caused go mod vendor to skip copying the relevant dependencies into the vendor directory. I’ve adjusted the dependencies accordingly. However, I’m curious—what's the purpose of using the go mod vendor command in the first place?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4a3f92e fixes the dependency issue. I'm able to run your example.
How can I see the localized error message?
I attempted a POST request, but it returned the following output:
curl -d '{"first_name":"foo"}' -H "Accept-Language: zh-TW" -H "Content-Type: application/json" -X POST http://localhost:8081/users
[{"User.FirstName":"FirstName is a required field","User.LastName":"LastName is a required field"}]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4a3f92e fixes the dependency issue. I'm able to run your example.
How can I see the localized error message? I attempted a POST request, but it returned the following output:
curl -d '{"first_name":"foo"}' -H "Accept-Language: zh-TW" -H "Content-Type: application/json" -X POST http://localhost:8081/users [{"User.FirstName":"FirstName is a required field","User.LastName":"LastName is a required field"}]
You can use the following command to get error messages in Traditional Chinese:
curl -d '{"first_name":"foo"}' -H "Accept-Language: zh-Hant-TW" -H "Content-Type: application/json" -X POST http://localhost:8081/users
Or use this command to get messages in Simplified Chinese:
curl -d '{"first_name":"foo"}' -H "Accept-Language: zh" -H "Content-Type: application/json" -X POST http://localhost:8081/users
No description provided.