Locale Starter
简介
Locale Starter 为 Hiboot 应用程序提供国际化(i18n)支持。它允许你通过配置文件管理翻译来创建多语言应用程序。
安装
在应用程序中导入 locale starter:
import "github.com/hidevopsio/hiboot/pkg/starter/locale"
配置
在 application.yml 中启用 locale:
app:
profiles:
include:
- locale
locale:
default: zh-CN
supported:
- en-US
- zh-CN
或通过代码启用:
package main
import (
"github.com/hidevopsio/hiboot/pkg/app"
"github.com/hidevopsio/hiboot/pkg/app/web"
"github.com/hidevopsio/hiboot/pkg/starter/locale"
)
func main() {
web.NewApplication().
SetProperty(app.ProfilesInclude, locale.Profile).
Run()
}
翻译文件
在 config/i18n 目录中创建翻译文件:
项目结构
config/
└── i18n/
├── en-US.yml
└── zh-CN.yml
config/i18n/en-US.yml
messages:
greeting: "Hello, {name}!"
welcome: "Welcome to our application"
errors:
not_found: "Resource not found"
unauthorized: "You are not authorized"
validation:
required: "This field is required"
email: "Please enter a valid email address"
user:
create_success: "User created successfully"
delete_success: "User deleted successfully"
config/i18n/zh-CN.yml
messages:
greeting: "你好,{name}!"
welcome: "欢迎使用我们的应用"
errors:
not_found: "资源未找到"
unauthorized: "您未获得授权"
validation:
required: "此字段为必填项"
email: "请输入有效的电子邮件地址"
user:
create_success: "用户创建成功"
delete_success: "用户删除成功"
基本用法
注入 Locale 服务
package controller
import (
"github.com/hidevopsio/hiboot/pkg/app"
"github.com/hidevopsio/hiboot/pkg/at"
"github.com/hidevopsio/hiboot/pkg/model"
"github.com/hidevopsio/hiboot/pkg/starter/locale"
)
type userController struct {
at.RestController
at.RequestMapping `value:"/user"`
locale locale.Service
}
func init() {
app.Register(newUserController)
}
func newUserController(locale locale.Service) *userController {
return &userController{
locale: locale,
}
}
func (c *userController) Post(request *CreateUserRequest) (model.Response, error) {
// 创建用户...
response := new(model.BaseResponse)
response.SetMessage(c.locale.Get("user.create_success"))
return response, nil
}
带参数的翻译
func (c *userController) GetGreeting(name string) (model.Response, error) {
// 获取带占位符替换的翻译
greeting := c.locale.GetWithParams("messages.greeting", map[string]string{
"name": name,
})
response := new(model.BaseResponse)
response.SetData(greeting)
return response, nil
}
语言检测
从 Accept-Language 头
locale 服务自动从 Accept-Language HTTP 头检测用户首选语言:
func (c *userController) Get() (model.Response, error) {
// 从请求上下文获取语言
lang := c.Ctx.GetHeader("Accept-Language")
// 使用特定语言的 locale 服务
message := c.locale.GetForLocale(lang, "messages.welcome")
response := new(model.BaseResponse)
response.SetData(message)
return response, nil
}
从查询参数
允许用户通过查询参数指定语言:
func (c *userController) Get(lang string) (model.Response, error) {
if lang == "" {
lang = "zh-CN" // 默认
}
message := c.locale.GetForLocale(lang, "messages.welcome")
response := new(model.BaseResponse)
response.SetData(message)
return response, nil
}
API 参考
locale.Service 接口
type Service interface {
// Get 返回当前语言的翻译
Get(key string) string
// GetWithParams 返回带占位符替换的翻译
GetWithParams(key string, params map[string]string) string
// GetForLocale 返回指定语言的翻译
GetForLocale(locale, key string) string
// GetForLocaleWithParams 返回指定语言带参数的翻译
GetForLocaleWithParams(locale, key string, params map[string]string) string
// SetLocale 设置当前语言
SetLocale(locale string)
// GetLocale 返回当前语言
GetLocale() string
}
错误消息示例
package controller
import (
"github.com/hidevopsio/hiboot/pkg/app"
"github.com/hidevopsio/hiboot/pkg/at"
"github.com/hidevopsio/hiboot/pkg/model"
"github.com/hidevopsio/hiboot/pkg/starter/locale"
)
type apiController struct {
at.RestController
at.RequestMapping `value:"/api"`
locale locale.Service
}
func init() {
app.Register(newApiController)
}
func newApiController(locale locale.Service) *apiController {
return &apiController{
locale: locale,
}
}
func (c *apiController) GetById(id uint64) (model.Response, error) {
resource, err := findResource(id)
if err != nil {
response := new(model.BaseResponse)
response.SetCode(404)
response.SetMessage(c.locale.Get("errors.not_found"))
return response, nil
}
response := new(model.BaseResponse)
response.SetData(resource)
return response, nil
}
验证消息
与验证集成以获得本地化的错误消息:
func (c *userController) Post(request *CreateUserRequest) (model.Response, error) {
// 验证请求
if request.Email == "" {
response := new(model.BaseResponse)
response.SetCode(400)
response.SetMessage(c.locale.Get("errors.validation.required"))
return response, nil
}
if !isValidEmail(request.Email) {
response := new(model.BaseResponse)
response.SetCode(400)
response.SetMessage(c.locale.Get("errors.validation.email"))
return response, nil
}
// 继续创建用户...
}
配置参考
| 属性 | 描述 | 默认值 |
|---|---|---|
locale.default |
默认语言 | en-US |
locale.supported |
支持的语言列表 | ["en-US"] |
最佳实践
- 组织翻译:将相关翻译分组到公共前缀下
- 使用占位符:使用
{param}语法表示动态内容 - 提供回退:始终有一个包含完整翻译的默认语言
- 保持键一致:在所有语言文件中使用相同的键
- 避免硬编码:永远不要在代码中硬编码面向用户的字符串
下一步
- Actuator Starter - 健康检查和指标
- Logging Starter - 结构化日志
- 自动配置 - 创建自定义 Starter