目录

Go语言项目实现多语言切换

一、实现

使用 go-i18n 包,实现将你的go程序翻译成多种语言

go get github.com/nicksnyder/go-i18n/v2/i18n

(一)预定义多语言文本

/config
  /locales
    en.json  # 英文
    zh.json  # 中文
    ja.json  # 日文

项目存储多语言文本json

例子:zh.json

// zh.json
{
  "welcome": "欢迎访问!当前时间:{{.Now}}",
  "error_404": "页面不存在",
  "button": {
    "submit": "提交"
  }
}

key 就是渲染html页面的变量,val就是展示的文本

(二)初始化i18n加载器

import "github.com/nicksnyder/go-i18n/v2/i18n"
bundle := i18n.NewBundle(language.English)
func InitLocales() {
    langs := []string{"en", "zh", "ja"}
    for _, lang := range langs {
        bundle := i18n.NewBundle(language.Make(lang))
        bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
        file, _ := os.ReadFile(fmt.Sprintf("config/locales/%s.json", lang))
        bundle.MustParseMessageFileBytes(file, lang+".json")
        bundles[lang] = bundle
    }
}

(三)动态获取翻译文本

例子一:以 http 的 header 进行识别

// 根据请求头切换语言
func GetTranslator(r *http.Request) *i18n.Localizer {
    accept := r.Header.Get("Accept-Language")
    tag, _, _ := language.ParseAcceptLanguage(accept)
    return i18n.NewLocalizer(bundles["zh"], tag...)
}

// 使用示例
func Handler(w http.ResponseWriter, r *http.Request) {
    loc := GetTranslator(r)
    msg := loc.MustLocalize(&i18n.LocalizeConfig{
        MessageID: "welcome",
        TemplateData: map[string]interface{}{
            "Now": time.Now().Format("2006-01-02"),
        },
    })
    fmt.Fprint(w, msg)
}

例子二:Gin框架集成

// 中间件注入语言包
func I18nMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        loc := i18n.NewLocalizer(bundle, c.GetHeader("Accept-Language"))
        c.Set("loc", loc)
        c.Next()
    }
}

// 控制器调用
func Welcome(c *gin.Context) {
    loc := c.MustGet("loc").(*i18n.Localizer)
    c.String(200, loc.MustLocalize("welcome"))
}

例子三、HTML模板动态渲染

注册一个模版函数,在模版重调用即可

<!-- 注册模板函数 -->
funcMap := template.FuncMap{
    "T": func(msgID string, args ...interface{}) string {
        return loc.MustLocalize(msgID, args...)
    }
}

<!-- 模板中使用 -->
<h1>{{T "welcome"}}</h1>
<button>{{T "button.submit"}}</button>

二、原理

其核心流程:

  • ​资源文件存储​​:按 lang.json 格式保存翻译文本

  • ​加载器解析​​:根据 Locale 加载对应语言包

  • ​模板注入​​:通过函数动态替换文本

本质上就是为项目预定义好多语言文本文件,然后根据语言进行切换

三、注意事项

  • 当某个变量的多语言不存在时,应该返回默认,而不是报错

  • 当切换某种语言不支持时,应该返回默认语言

  • 该方案可能存在内存问题,将 json 文件加载到内存,若翻译文件越大,内存占用越多

  • 应该是目前最流行多语言解决方案,但是存在缺陷:只能翻译固定的文本,像从数据库查询的文本则不支持翻译

你还知道哪些更优的方案吗

👏欢迎大家评论区分享留言!!!