golang支持上下文感知i18n国际化与复数处理的插件库ctxi18n的使用

Golang 支持上下文感知 i18n 国际化与复数处理的插件库 ctxi18n 的使用

介绍

ctxi18n 是一个受 Ruby on Rails 国际化功能启发的 Go 语言国际化库,旨在让 Go 应用的国际化变得简单直接。

主要特性:

  • 加载 YAML 或 JSON 格式的翻译文件
  • 轻松将 locale 对象添加到上下文中
  • 支持 fs.FS 加载数据
  • 提供简短的方法名如 i18n.T()i18n.N()
  • 支持简单的键值插值
  • 支持复数处理规则
  • 当翻译缺失时提供默认值

使用示例

基本使用

import "github.com/invopop/ctxi18n"

// 加载翻译文件
if err := ctxi18n.Load(assets.Content); err != nil {
    panic(err)
}

// 设置默认语言
if err := ctxi18n.LoadWithDefault(assets.Content, "en"); err != nil {
    panic(err)
}

// 在上下文中设置语言
ctx = ctxi18n.WithLocale(ctx, "en")
ctx = ctxi18n.WithLocale(ctx, "en-US,en;q=0.9,es;q=0.8")

翻译文件示例 (YAML)

en:
  welcome:
    title: "Welcome to our application!"
    login: "Log in"
    signup: "Sign up"
    forgot-password: "Forgot Password?"
es:
  welcome:
    title: "¡Bienvenido a nuestra aplicación!"
    login: "Ingresarse"
    signup: "Registrarse"
    forgot-password: "¿Olvidaste tu contraseña?"

获取翻译

有两种方式获取翻译:

  1. 直接使用包方法:
import "github.com/invopop/ctxi18n/i18n"

fmt.Println(i18n.T(ctx, "welcome.title"))
  1. 从上下文中提取 locale 对象:
l := ctxi18n.Locale(ctx)
fmt.Println(l.T("welcome.title"))

默认值处理

当翻译缺失时:

fmt.Println(l.T("welcome.no.text"))
// 输出: !(MISSING welcome.no.text)

// 使用默认值
fmt.Println(i18n.T(ctx, "welcome.question", i18n.Default("Just ask!")))
// 输出: "Just ask!"

// 检查翻译是否存在
if !i18n.Has(ctx, "welcome.question") {
  fmt.Println("Just ask!")
}

插值

en:
  welcome:
    title: "Hi %{name}, welcome to our App!"
i18n.T(ctx, "welcome.title", i18n.M{"name":"Sam"})

// 带默认值的插值
i18n.T(ctx, "welcome.title", i18n.Default("Hi %{name}"), i18n.M{"name":"Sam"})

复数处理

en:
  inbox:
    emails:
      zero: "You have no emails."
      one: "You have %{count} email."
      other: "You have %{count} emails."
count := 2
fmt.Println(i18n.N(ctx, "inbox.emails", count, i18n.M{"count": count}))
// 输出: "You have 2 emails."

作用域

ctx := i18n.WithScope(ctx, "welcome")
i18n.T(ctx, ".title", i18n.M{"name":"Sam"})

与 Templ 集成

en:
  welcome:
    hello: "Hello, %{name}"
package main

import "github.com/invopop/ctxi18n/i18n"

templ Hello(name string) {
  <span class="hello">
    { i18n.T(ctx, "welcome.hello", i18n.M{"name": name}) }
  </span>
}

templ Greeting(person Person) {
  <div class="greeting">
    @Hello(person.Name)
  </div>
}

完整示例

package main

import (
	"context"
	"fmt"
	"log"
	
	"github.com/invopop/ctxi18n"
	"github.com/invopop/ctxi18n/i18n"
)

func main() {
	// 初始化上下文
	ctx := context.Background()
	
	// 加载翻译文件 (假设已嵌入到 assets.Content)
	if err := ctxi18n.LoadWithDefault(assets.Content, "en"); err != nil {
		log.Fatal(err)
	}
	
	// 设置语言
	ctx = ctxi18n.WithLocale(ctx, "en")
	
	// 简单翻译
	fmt.Println(i18n.T(ctx, "welcome.title"))
	
	// 插值
	fmt.Println(i18n.T(ctx, "welcome.greeting", i18n.M{"name": "Alice"}))
	
	// 复数处理
	fmt.Println(i18n.N(ctx, "inbox.emails", 1, i18n.M{"count": 1}))
	fmt.Println(i18n.N(ctx, "inbox.emails", 5, i18n.M{"count": 5}))
	
	// 使用作用域
	ctx = i18n.WithScope(ctx, "welcome")
	fmt.Println(i18n.T(ctx, ".login"))
}

这个库提供了灵活的国际化解决方案,可以根据项目需求选择最适合的使用方式。


更多关于golang支持上下文感知i18n国际化与复数处理的插件库ctxi18n的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang支持上下文感知i18n国际化与复数处理的插件库ctxi18n的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang 上下文感知 i18n 国际化与复数处理 - ctxi18n 使用指南

ctxi18n 是一个支持上下文感知国际化(i18n)和复数处理的 Go 语言库,特别适合构建多语言 Web 应用。下面我将详细介绍其使用方法。

安装

go get github.com/nicksnyder/go-i18n/v2/i18n
go get github.com/gin-contrib/cache

基本使用

1. 初始化 i18n 包

import (
	"github.com/nicksnyder/go-i18n/v2/i18n"
	"golang.org/x/text/language"
)

func main() {
	// 创建 bundle 用于管理本地化文件
	bundle := i18n.NewBundle(language.English)
	
	// 注册 JSON 解析器
	bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
	
	// 加载语言文件
	bundle.MustLoadMessageFile("active.en.json")
	bundle.MustLoadMessageFile("active.zh.json")
}

2. 创建语言文件

active.en.json:

{
  "hello_world": "Hello World",
  "unread_email_count": {
    "one": "You have {{.Count}} unread email",
    "other": "You have {{.Count}} unread emails"
  }
}

active.zh.json:

{
  "hello_world": "你好世界",
  "unread_email_count": {
    "one": "你有 {{.Count}} 封未读邮件",
    "other": "你有 {{.Count}} 封未读邮件"
  }
}

3. 创建本地化器

func createLocalizer(lang string, bundle *i18n.Bundle) *i18n.Localizer {
	accept := []string{lang}
	return i18n.NewLocalizer(bundle, accept...)
}

上下文感知使用

1. 在 HTTP 请求中使用

func handler(w http.ResponseWriter, r *http.Request) {
	// 从请求中获取语言偏好
	acceptLanguage := r.Header.Get("Accept-Language")
	
	// 创建本地化器
	localizer := createLocalizer(acceptLanguage, bundle)
	
	// 翻译消息
	helloMsg, err := localizer.Localize(&i18n.LocalizeConfig{
		MessageID: "hello_world",
	})
	
	fmt.Fprint(w, helloMsg)
}

2. 复数处理

func getUnreadCountMessage(localizer *i18n.Localizer, count int) string {
	msg, err := localizer.Localize(&i18n.LocalizeConfig{
		MessageID: "unread_email_count",
		TemplateData: map[string]interface{}{
			"Count": count,
		},
		PluralCount: count,
	})
	
	if err != nil {
		return fmt.Sprintf("You have %d unread emails", count)
	}
	return msg
}

高级功能

1. 上下文相关翻译

{
  "greeting": {
    "morning": "Good morning",
    "afternoon": "Good afternoon",
    "evening": "Good evening"
  }
}
func getGreeting(localizer *i18n.Localizer, period string) string {
	msg, err := localizer.Localize(&i18n.LocalizeConfig{
		MessageID: "greeting." + period,
	})
	
	if err != nil {
		return "Hello"
	}
	return msg
}

2. 默认值和回退

msg, err := localizer.Localize(&i18n.LocalizeConfig{
	DefaultMessage: &i18n.Message{
		ID:    "welcome_message",
		Other: "Welcome!",
	},
})

3. 与 Gin 框架集成

func i18nMiddleware(bundle *i18n.Bundle) gin.HandlerFunc {
	return func(c *gin.Context) {
		lang := c.GetHeader("Accept-Language")
		localizer := i18n.NewLocalizer(bundle, lang)
		c.Set("localizer", localizer)
		c.Next()
	}
}

func main() {
	r := gin.Default()
	r.Use(i18nMiddleware(bundle))
	
	r.GET("/hello", func(c *gin.Context) {
		localizer := c.MustGet("localizer").(*i18n.Localizer)
		msg, _ := localizer.Localize(&i18n.LocalizeConfig{
			MessageID: "hello_world",
		})
		c.String(200, msg)
	})
	
	r.Run()
}

最佳实践

  1. 组织语言文件:按功能模块拆分语言文件,便于维护
  2. 缓存翻译:对频繁使用的翻译结果进行缓存
  3. 测试覆盖:确保所有语言路径都被测试
  4. 回退策略:定义明确的回退语言顺序
  5. 动态内容:确保模板变量有合理的默认值

ctxi18n 提供了强大的国际化支持,通过上下文感知和复数处理能力,可以轻松构建适应全球用户的应用程序。

回到顶部