star 最多的 Go 语言本地化库|GitHub 2.8K

star,go,github,8k · 浏览次数 : 11

小编点评

### 原文 🌟 如果你是一位 Go 用户,可以在我开源的学习仓库中,找到针对各种往期归档文章,及学习资料。 📺 B站:白泽talk,公众号【白泽talk】,回复"电子书",即可获得包含《100个Go经典错误场景》在内的纯净 Golang 电子书大全。 一、什么是本地化 今天讲讲 i18n,无论是 ToB 还是 ToC 的业务,常常存在多语言的需求,由于用户有时来自不同国家,因此需要对页面展示内容,包括响应结果做多语言的适配。 hello world! → 你好世界! err: "user not find" → err: "用户不存在" ⚠️ 如果发生了翻译错误,可能会让人十分困扰,参考鸣潮最近的一个类似的事故: 鸣潮日文客户端将本次up角色忌炎的专武效果翻译错误,将R技能翻译成了E技能。 二、前后端的不同实现在前端实现国际化准备多语言资源文件:首先,需要准备多语言的资源文件,包括不同语言版本的字符串。 集成国际化插件:使用前端框架提供的国际化插件,如 React-intl、Vue-i18n 等,或者手动实现国际化逻辑。 根据用户选择的语言加载资源:在应用加载时,根据用户选择的语言加载对应的资源文件,将界面展示的文本内容替换为对应语言的字符串。 在后端实现国际化准备多语言内容:将不同语言版本的文本或内容保存在后端,可以是数据库中、文件中或其他形式。 处理国际化逻辑:在后端代码中编写逻辑,根据用户的语言选择加载相应的内容。这可以通过模板引擎、多语言资源文件或者接口返回不同语言的数据来实现。 提供接口或服务:如果后端需要提供国际化服务,可以设计接口或服务来根据用户需求返回对应语言的内容。 三、Go 实现消息本地化🔥 最热门的项目:https://github.com/nicksnyder/go-i18n 本地化消息的定义与翻译流程🌟 这部分具体参看 go-i18n 的 readme 更加! 命令行工具下载(用于从 Go 代码中,提取需要本地化的 Message) go install -v github.com/nicksnyder/go-i18n/v2/goi18n@latest 创建两个文件存放翻译结果active.en.tomlactive.zh.toml 在 Go 代码中,显示声明一个 Message 结构 localizer.Localize(&i18n.LocalizeConfig{ DefaultMessage: &i18n.Message{ ID: "PersonCats", One: "{{.Name}} has {{.Count}} cat.", Other: "{{.Name}} has {{.Count}} cats.", }, TemplateData: map[string]interface{}{ "Name": "Nick", "Count": 2, }, PluralCount: 2, }) // Nick has 2 cats. 执行 CMD 命令,将 Message 信息提取到 active.en.toml 文件中 goi18n extract# active.eng.toml[PersonCats]description = "The number of cats a person has" one = "{{.Name}} has {{.Count}} cat." other = "{{.Name}} has {{.Count}} cats." 执行 CMD 命令,将待翻译成中文的 Message 提取到 translate.zh.toml 文件中(这个文件是工具创建的) goi18n merge active.*.toml# translate.zh.toml[HelloPerson]hash = "sha1-5b49bfdad81fedaeefb224b0ffc2acc58b09cff5" other = "Hello {{.Name}}" 执行 CMD 命令将 translate.zh.toml 内的翻译好的内容,自动增量合并进入 active.zh.toml 文件中 goi18n merge active.*.toml translate.*.toml 四、基于 go-i18n 进一步封装实现一个 HTTP 服务 🌟 见 demo:https://github.com/BaiZe1998/go-learning/tree/main/kit/i18n 效果:从 HTTP 头部中获取 lang,得到“zh”,响应中文的错误消息。 一个简单的 HTTP 服务 创建一个具备本地化能力的 error,从请求头提取语言,然后选择对应语言的error信息响应。 func helloHandler(w http.ResponseWriter, r *http.Request) { err := NewUserNotFoundErr(123) // err, _ := someFunc() fmt.Fprintf(w, FormatErr(err)) } func main() { http.HandleFunc("/", helloHandler) fmt.Println("Starting server on port 8080... ") if err := http.ListenAndServe(":8080", nil); err != nil { log.Fatal(err) } } 服务启动前初始化默认语言选择中文,选择将 active.zh.toml 在服务启动前加载进入内存。 var ( bundle = i18n.NewBundle(language.English)) func init() { bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal) bundle.LoadMessageFile("active.zh.toml") } 高效封装以下的封装确保每次新增一个本地化的 error,只需要组合 BaseError,即可继承通用的本地化能力。 // 本地化方法声明 type LocalizedError interface { Error() string LocalizedID() string TemplateData() map[string]interface{} } // 基础错误类,实现对应本地化方法 type BaseError struct { ID string DefaultMessage string TempData map[string]interface{} } func (b BaseError) Error() string { return b.DefaultMessage } func (b BaseError) LocalizedID() string { return b.ID } func (b BaseError) TemplateData() map[string]interface{} { return b.TempData } // 新增一个自定义错误 type UserNotFoundErr struct { BaseError } func NewUserNotFoundErr(userID int) LocalizedError { msg := i18n.Message{ ID: "user_not_found", Other: "User not found {{.UserID}}", } e := UserNotFoundErr{} e.ID = msg.ID e.DefaultMessage = msg.Other e.TempData = map[string]interface{}{ "UserID": userID, } return e } 提取本地化的 err 消息 由于所有具备本地化能力的 err 都实现了 LocalizedError 接口,因此可以定义如下方法统一在 Handler 层提取本地化之后的错误内容。 // 这里就不从 HTTP 请求头获取了,假设提取到了 zh func GetLang(_ context.Context) string { return "zh" } func FormatErr(err error) string { lang := GetLang(context.Background()) loc := i18n.NewLocalizer(bundle, lang) var i18nErr LocalizedError if errors.As(err, &i18nErr) { msg, _ := locLocalize(&i18n.LocalizeConfig{ DefaultMessage: &i18n.Message{ ID: i18nErr.LocalizedID(), Other: i18nErr.Error(), }, //MessageID: i18nErr.LocalizedID(): TemplateData: i18nErr.TemplateData(), }) return msg } return err.Error() } 五、学习资料 参考文献: Xuanwo's Blog掘金:Go语言国际化 i18n Go Web 编程 https://www.ituring.com.cn/article/508191?published=true 开源仓库: https://github.com/nicksnyder/go-i18n https://github.com/gin-contrib/i18n https://github.com/hertz-contrib/i18n https://github.com/gofiber/contrib/tree/main/fiberi18n https://github.com/beego/i18n。 归纳总结

正文

🌟 如果你是一位 Go 用户,可以在我开源的学习仓库中,找到针对各种往期归档文章,及学习资料。

📺 B站:白泽talk,公众号【白泽talk】,回复"电子书",即可获得包含《100个Go经典错误场景》在内的纯净 Golang 电子书大全。

一、什么是本地化

今天讲讲 i18n,无论是 ToB 还是 ToC 的业务,常常存在多语言的需求,由于用户有时来自不同国家,因此需要对页面展示内容,包括响应结果做多语言的适配。

hello world! -> 你好世界! err: "user not find" -> err: "用户不存在"

⚠️ 如果发生了翻译错误,可能会让人十分困扰,参考鸣潮最近的一个类似的事故:

鸣潮日文客户端将本次up角色忌炎的专武效果翻译错误,将R技能翻译成了E技能。

image-20240611215931184

二、前后端的不同实现

在前端实现国际化

  1. 准备多语言资源文件:首先,需要准备多语言的资源文件,包括不同语言版本的字符串。
  2. 集成国际化插件:使用前端框架提供的国际化插件,如 React-intl、Vue-i18n 等,或者手动实现国际化逻辑。
  3. 根据用户选择的语言加载资源:在应用加载时,根据用户选择的语言加载对应的资源文件,将界面展示的文本内容替换为对应语言的字符串。

在后端实现国际化

  1. 准备多语言内容:将不同语言版本的文本或内容保存在后端,可以是数据库中、文件中或其他形式。
  2. 处理国际化逻辑:在后端代码中编写逻辑,根据用户的语言选择加载相应的内容。这可以通过模板引擎、多语言资源文件或者接口返回不同语言的数据来实现。
  3. 提供接口或服务:如果后端需要提供国际化服务,可以设计接口或服务来根据用户需求返回对应语言的内容。

三、Go 实现消息本地化

🔥 最热门的项目:https://github.com/nicksnyder/go-i18n

image-20240611220901762

本地化消息的定义与翻译流程

🌟 这部分具体参看 go-i18n 的 readme 更加!

  1. 命令行工具下载(用于从 Go 代码中,提取需要本地化的 Message)
go install -v github.com/nicksnyder/go-i18n/v2/goi18n@latest
  1. 创建两个文件存放翻译结果
active.en.toml
active.zh.toml
  1. 在 Go 代码中,显示声明一个 Message 结构
localizer.Localize(&i18n.LocalizeConfig{
    DefaultMessage: &i18n.Message{
        ID: "PersonCats",
        One: "{{.Name}} has {{.Count}} cat.",
        Other: "{{.Name}} has {{.Count}} cats.",
    },
    TemplateData: map[string]interface{}{
        "Name": "Nick",
        "Count": 2,
    },
    PluralCount: 2,
}) // Nick has 2 cats.
  1. 执行 CMD 命令,将 Message 信息提取到 active.en.toml 文件中
goi18n extract

# active.en.toml
[PersonCats]
description = "The number of cats a person has"
one = "{{.Name}} has {{.Count}} cat."
other = "{{.Name}} has {{.Count}} cats."
  1. 执行 CMD 命令,将待翻译成中文的 Message 提取到 translate.zh.toml 文件中(这个文件是工具创建的)
goi18n merge active.*.toml

# translate.zh.toml
[HelloPerson]
hash = "sha1-5b49bfdad81fedaeefb224b0ffc2acc58b09cff5"
other = "Hello {{.Name}}"
  1. 将 translate.zh.toml 翻译成中文
# translate.zh.toml
[HelloPerson]
hash = "sha1-5b49bfdad81fedaeefb224b0ffc2acc58b09cff5"
other = "你好 {{.Name}}"
  1. 执行 CMD 命令将 translate.zh.toml 内的翻译好的内容,自动增量合并进入 active.zh.toml 文件中
goi18n merge active.*.toml translate.*.toml

四、基于 go-i18n 进一步封装实现一个 HTTP 服务

🌟 见 demo:https://github.com/BaiZe1998/go-learning/tree/main/kit/i18n

效果:从 HTTP 头部中获取 lang,得到“zh”,响应中文的错误消息。

image-20240611223711746

一个简单的 HTTP 服务

创建一个具备本地化能力的 error,从请求头提取语言,然后选择对应语言的error信息响应。

func helloHandler(w http.ResponseWriter, r *http.Request) {
	err := NewUserNotFoundErr(123)
	//err, _ := someFunc()
	fmt.Fprintf(w, FormatErr(err))
}

func main() {
	http.HandleFunc("/", helloHandler)

	fmt.Println("Starting server on port 8080...")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal(err)
	}
}

服务启动前初始化

默认语言选择中文,选择将 active.zh.toml 在服务启动前加载进入内存。

var (
	bundle = i18n.NewBundle(language.English)
)

func init() {
	bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
	bundle.LoadMessageFile("active.zh.toml")
}

高效封装

以下的封装确保每次新增一个本地化的 error,只需要组合 BaseError,即可继承通用的本地化能力。

// 本地化方法声明
type LocalizedError interface {
	error
	LocalizedID() string
	TemplateData() map[string]interface{}
}

// 基础错误类,实现对应本地化方法
type BaseError struct {
	ID             string
	DefaultMessage string
	TempData       map[string]interface{}
}

func (b BaseError) Error() string {
	return b.DefaultMessage
}

func (b BaseError) LocalizedID() string {
	return b.ID
}

func (b BaseError) TemplateData() map[string]interface{} {
	return b.TempData
}

// 新增一个自定义错误
type UserNotFoundErr struct {
	BaseError
}

func NewUserNotFoundErr(userID int) LocalizedError {
	msg := i18n.Message{
		ID:    "user_not_found",
		Other: "User not found {{.UserID}}",
	}
	e := UserNotFoundErr{}
	e.ID = msg.ID
	e.DefaultMessage = msg.Other
	e.TempData = map[string]interface{}{
		"UserID": userID,
	}
	return e
}

提取本地化的 err 消息

由于所有具备本地化能力的 err 都实现了 LocalizedError 接口,因此可以定义如下方法统一在 Handler 层提取本地化之后的错误内容。

// 这里就不从 HTTP 请求头获取了,假设提取到了 zh
func GetLang(_ context.Context) string {
	return "zh"
}

func FormatErr(err error) string {
	lang := GetLang(context.Background())
	loc := i18n.NewLocalizer(bundle, lang)
	var i18nErr LocalizedError
	if errors.As(err, &i18nErr) {
		msg, _ := loc.Localize(&i18n.LocalizeConfig{
			DefaultMessage: &i18n.Message{
				ID:    i18nErr.LocalizedID(),
				Other: i18nErr.Error(),
			},
			//MessageID: i18nErr.LocalizedID(),
			TemplateData: i18nErr.TemplateData(),
		})
		return msg
	}
	return err.Error()
}

五、学习资料

参考文献:

开源仓库:

与star 最多的 Go 语言本地化库|GitHub 2.8K相似的内容:

star 最多的 Go 语言本地化库|GitHub 2.8K

今天讲讲 i18n,无论是 ToB 还是 ToC 的业务,常常存在多语言的需求,由于用户有时来自不同国家,因此需要对页面展示内容,包括响应结果做多语言的适配。

golang开发 gorilla websocket的使用

很多APP都需要主动向用户推送消息,这就需要用到长连接的服务,即我们通常提到的websocket,同样也是使用socket服务,通信协议是基本类似的,在go中用的最多的、也是最简单的socket服务就是gorilla/websocket,它有21.1K的star,足以说明它的受欢迎程度, 它的git

图解计算机的存储器金字塔

本文已收录到 GitHub · AndroidFamily,有 Android 进阶知识体系,欢迎 Star。技术和职场问题,请关注公众号 [彭旭锐] 进 Android 面试交流群。 前言 大家好,我是小彭。 在计算机组成原理中的众多概念中,开发者接触得最多的还是内存、硬盘、虚拟内存、CPU 缓存

30K Star,最全面的PDF处理开源项目,你也可以拥有一个本地的PDF处理大全

大家好,我是程序猿DD 今天给大家推荐一个日常大概率能用上的开源项目:Stirling PDF 开源地址:https://github.com/Stirling-Tools/Stirling-PDF Stirling PDF是一个可以用Docker在本地托管的基于Web的PDF处理工具。它的功能非常

从图灵机到量子计算机,计算机可以解决所有问题吗?

本文已收录到 GitHub · AndroidFamily,有 Android 进阶知识体系,欢迎 Star。技术和职场问题,请关注公众号 [彭旭锐] 进 Android 面试交流群。 前言 大家好,我是小彭。 今天,我们正式开启一个新专栏 —— 计算机组成原理。 计算机组成原理是计算机科学中最基础

又一个开源便斩获 7k star 的新模型「GitHub 热点速览」

Star 并不能代表什么,但是绝对能表示一个项目的受欢迎程度。就像刚开源一周就有 7k+ star 的新模型,输入文本 / 图像就能获得 3D 对象。除了这个新模型,本周还有一款新的 Web 3D 渲染引擎 Orillusion,向量数据库新晋成员 qdrant。还有老牌魔兽世界为它站台的游戏解决方

GitHub Star 数量前 12 的开源无代码工具

相关文章:GitHub Star 数量前 15 的开源低代码项目 在本篇文章中,我们将探索 12 款在 GitHub 上星级排名前列的开源无代码工具。 每款工具都旨在简化和加速开发过程,但各自侧重于不同的应用场景。 从动态表单生成的 Formily,到高度可定制的 NocoBase 用于复杂业务系统

强烈推荐:18.3k star,推荐一款简单易用的HTTP请求流量录制回放工具:Goreplay

在软件开发和测试过程中,我们经常需要对应用程序的网络请求进行录制和回放,以便进行性能分析、压力测试或者模拟复杂的网络环境。今天,我要向大家推荐一款简单易用的 HTTP 请求流量录制回放工具:Goreplay。 1、简介 Goreplay 是一款用 Go 语言编写的 HTTP 请求流量录制回放工具。它

4.4K Star!推荐一款新一代的极简监控系统!轻量高性能!超500个监控指标,颜值高、功能强大!

在信息化快速发展的今天,企业运维面临的挑战日益增多。传统的运维监控系统往往存在功能冗余、性能低下、操作复杂等问题,难以满足现代企业对高效、稳定、智能的运维管理需求。 今天给大家推荐一款新一代极简运维监控系统:WGCLOUD 1、介绍 WGCLOUD是一个基于Java开发的高性能、高并发的分布式监控系

18.9k star!一个高性能的嵌入式分析型数据库,主要用于数据分析和数据处理任务。

大家好,今天给大家分享的是一个开源的面向列的关系数据库管理系统(RDBMS)。 DuckDB是一个嵌入式的分析型数据库,它提供了高性能的数据分析和数据处理能力。DuckDB的设计目标是为数据科学家、分析师和数据工程师提供一个快速、灵活且易于使用的数据分析工具。它支持SQL查询语言,并提供了一系列高级