* matchs to matches * contraint to constraint * resovle to resolver * ser to set Signed-off-by: kwanhur <huang_hua2012@163.com>
4.4 KiB
i18n Example
This project is an demo for i18n usage. We integrated go-i18n into our project for localization.
We start with the project generate with kratos-layout, you could use kratos new to generate it.
The following steps are applied.
Step 1: install
Install the cli tool goi18n and the package.
go get -u github.com/nicksnyder/go-i18n/v2/goi18n
go get -u github.com/nicksnyder/go-i18n
Step 2: implement and register the middleware
There's a middleware in internal/pkg/middleware/localize,
we implement this middleware, and register it into our http server in internal/server/http.go.
We init the bundle and load our translation file(we will generate it later).
For convenience, we hard-coded the translation file path here, you should avoid it in your project :)
Also the middleware will extract accept-language header
from our request, then set the correct localizer to the context.
In our service request handler, we can use the FromContext method to get this localizer for localization.
This middleware is so simple that we can show it as following:
package localize
import (
"context"
"github.com/BurntSushi/toml"
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/transport"
)
type localizerKey struct{}
func I18N() middleware.Middleware {
bundle := i18n.NewBundle(language.English)
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
bundle.MustLoadMessageFile("../../active.zh.toml")
return func(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
if tr, ok := transport.FromServerContext(ctx); ok {
accept := tr.Header().Get("accept-language")
println(accept)
localizer := i18n.NewLocalizer(bundle, accept)
ctx = context.WithValue(ctx, localizerKey{}, localizer)
}
return handler(ctx, req)
}
}
}
func FromContext(ctx context.Context) *i18n.Localizer {
return ctx.Value(localizerKey{}).(*i18n.Localizer)
}
Step 3:
Write our request handler code.
In internal/service/greeter.go, we use localize.FromContext(ctx) to get the localizer, and write the string for localizing.
You should write your message with golang template syntax.
Notice that both One and Other fields must be filled or you will get an panic on translation file generation with goi18n tool.
func (s *GreeterService) SayHello(ctx context.Context, in *v1.HelloRequest) (*v1.HelloReply, error) {
s.log.WithContext(ctx).Infof("SayHello Received: %v", in.GetName())
if in.GetName() == "error" {
return nil, v1.ErrorUserNotFound("user not found: %s", in.GetName())
}
localizer := localize.FromContext(ctx)
helloMsg, err := localizer.Localize(&i18n.LocalizeConfig{
DefaultMessage: &i18n.Message{
Description: "sayhello",
ID: "sayHello",
One: "Hello {{.Name}}",
Other: "Hello {{.Name}}",
},
TemplateData: map[string]interface{}{
"Name": in.Name,
},
})
if err != nil {
return nil, err
}
return &v1.HelloReply{Message: helloMsg}, nil
}
Step 3: Generate and translate
In the root of this project, generate active.en.toml with
goi18n extract
The string which should be translated will be extracted from your code, and write into active.en.toml
You should create the empty target language file:
touch translate.zh.toml
Then fill the translate file:
goi18n merge active.en.toml translate.zh.toml
You should edit the translate.zh.toml to finish the translation work. We translate Hello to 你好 in Chinese.
After that, you should rename this file to active.zh.toml
And this file is the translation file that we load in the Step 2.
You could also embed these translation files into your binaries for easier deployment.
Step 4: Run
Go to cmd/i18n/, and run go run . to start the service.
You could try with curl with Accept-Language header
curl "http://localhost:8000/helloworld/eric" \
-H 'Accept-Language: zh-CN'
Will get the Chinese result {"message":"你好 eric"}
And if no header:
curl "http://localhost:8000/helloworld/eric"
Will get the default English result {"message":"Hello eric"}
Reference
- go-i18n You could refer to this repository for more detailed document.