star 最多的 Go 语言本地化库|GitHub 2.8K
如果你是一位 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.toml
active.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.en.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}}"
- 将 translate.zh.toml 翻译成中文
# translate.zh.toml
[HelloPerson]
hash = "sha1-5b49bfdad81fedaeefb224b0ffc2acc58b09cff5"
other = "你好 {{.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
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()
}
五、学习资料
参考文献:
开源仓库:
- 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
star 最多的 Go 语言本地化库|GitHub 2.8K的更多相关文章
- 在github上查找star最多的项目
如何在github上查找star最多的项目 在search中输入stars:>1 就可以查找所有有star的项目,然后右上角根据自己的需要筛选 当我输入stars:>10000的时候,就会 ...
- Standard C 语言标准函数库介绍
全面巩固所知所学,往精通方向迈进! Standard C 语言标准函数库速查 (Cheat Sheet) from:http://ganquan.info/standard-c/function/ C ...
- 全网Star最多(近20k)的Spring Boot开源教程 2019 年要继续更新了!
从2016年1月开始写博客,默默地更新<Spring Boot系列教程>,从无人问津到千万访问,作为一个独立站点(http://blog.didispace.com),相信只有那些跟我一样 ...
- Standard C 语言标准函数库速查(彩色的函数列表,十分清楚)
Standard C 语言标准函数库速查 (Cheat Sheet) wcstombs 函数说明 #include <stdlib.h> size_t mbstowcs(wchar_t * ...
- 黄聪:让WordPress主题支持语言本地化(使用poedit软件实现中文翻译功能)
如果你的WordPress主题要提交到WordPress官方主题库,使用者来自世界各地的多种语言,那么,你就要让你的WordPress主题支持语言本地化,方便使用者进行语言翻译和制作语言包. 让Wor ...
- [Abp 源码分析]十三、多语言(本地化)处理
0.简介 如果你所开发的需要走向世界的话,那么肯定需要针对每一个用户进行不同的本地化处理,有可能你的客户在日本,需要使用日语作为显示文本,也有可能你的客户在美国,需要使用英语作为显示文本.如果你还是一 ...
- Redis学习之路(008)- Redis C语言客户端库hiredis文档翻译
Hiredis是Redis数据库一个轻量的C语言客户端库. 之所以轻量是由于它只是简单的提供了对redis操作语句支持的接口,并没有实现具体的操作语句的功能.但正是由于这种设计使我们只要熟悉了通用的r ...
- C语言函数库
C语言函数库 分类函数目录函数进程函数诊断函数接口子程序输入输出 str字符串操作函数mem操作存贮数组 数学函数 时间日期函数 转换函数 分类函数,所在函数库为ctype.h[top] int is ...
- unity多语言本地化
简介 嗯...一般来说做游戏啥的都不会只发一个国家,但是每个国家语言不同,就存在多语言本地化的问题,然后直接用过一个通过xml完成本地化的东东,然后策划反馈不会修改xml,扔给我一个excel让我自己 ...
- 造!又有新的生产力语言了「GitHub 热点速览 v.22.30」
作者:HelloGitHub-小鱼干 你还记得那些 PHP 开发都去哪了吗?转 Golang 了!移动端现在流行什么?Flutter 编程.现在谷歌带着新的生产力语言来了,Carbon,代号:C++ ...
随机推荐
- ECharts海量数据渲染解决卡顿的4种方式
场景 周五进行需求评审的时候: 出现了一个图表,本身一个图表本没有什么稀奇的: 可是产品经理在图表的上的备注,让我觉得这个事情并不简单: 那个图表的时间跨度可以是月,年,而且时间间隔很短: 这让我意识 ...
- 聊聊日志硬扫描,阿里 Log Scan 的设计与实践
简介: SLS 新推出 Scan 功能,让未索引的字段也支持搜索(硬扫描模式),节省全量索引产生的构建和存储费用,同时 Scan 的运行时计算模式对于杂乱结构的日志数据有更好的适配,帮助企业客户实现数 ...
- 为了让你在“口袋奇兵”聊遍全球,Serverless 做了什么?
简介: 江娱互动是一家新兴的游戏企业,自 2018 年成立伊始,江娱互动就面向广阔的全球游戏市场,通过创造有趣的游戏体验,在竞争激烈的游戏市场占得一席之地.仅仅 2 年的时间,江娱互动就凭借 Topw ...
- 淘宝推荐、视频搜索背后的检索技术竟是它!深度揭秘达摩院向量检索引擎Proxima
简介: 淘宝搜索推荐.视频搜索的背后使用了什么样的检索技术?非结构化数据检索,向量检索,以及多模态检索,它们到底解决了什么问题?今天由阿里巴巴达摩院的科学家从业务问题出发,抽丝剥茧,深度揭秘达摩院内部 ...
- 一文读懂容器存储接口 CSI
简介: 在<一文读懂 K8s 持久化存储流程>一文我们重点介绍了 K8s 内部的存储流程,以及 PV.PVC.StorageClass.Kubelet 等之间的调用关系.接下来本文将将重点 ...
- 重温设计模式之 Factory
简介: 创建型模式的核心干将,工厂.简单工厂.抽象工厂,还记得清么,一文回顾和对比下. 作者 | 弥高来源 | 阿里技术公众号 前言 创建型模式的核心干将,工厂.简单工厂.抽象工厂,还记得清么,一文回 ...
- 最佳实践丨云上虚拟IDC(私有池)如何为客户业务的确定性、连续性保驾护航
简介: 企业业务上云后,还面临特定可用区购买云上特定计算产品实例失败的困境?云上私有池pick一下 Why 云上业务为什么需要资源确定性.服务连续性 云计算正朝着像水电煤一样的基础设施演进,支持用户 ...
- [TP5] 浅谈 ThinkPHP 的 Hook 行为事件及监听执行
TP5 中使用 \think\Hook::add('xx', '\app\xxx\behavior\Xx') 注册行为. 也可以在 application/tags.php 中统一注册. 在需要监听执 ...
- SAP Adobe Form 教程六 FormCalc和JavaScript的实践
前文: SAP Adobe Form 教程一 简单示例 SAP Adobe Form 教程二 表 SAP Adobe Form 教程三 日期,时间,floating field SAP Adobe F ...
- linux-centos7.6-gpt-uefi安装
目录 linux-centos7.6-gpt-uefi安装 一.需要 二.环境 三.vm新建虚拟机系统环境 四.开始安装 linux-centos7.6-gpt-uefi安装 一.需要 安装的系统适用 ...