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"]

最佳实践

  1. 组织翻译:将相关翻译分组到公共前缀下
  2. 使用占位符:使用 {param} 语法表示动态内容
  3. 提供回退:始终有一个包含完整翻译的默认语言
  4. 保持键一致:在所有语言文件中使用相同的键
  5. 避免硬编码:永远不要在代码中硬编码面向用户的字符串

下一步