恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
listmonk 国际化(i18n)完全指南:语言包结构、自定义加载与贡献新语言
首页
资讯中心
/
listmonk 国际化(i18n)完全指南:语言包结构、自定义加载与贡献新语言
listmonk 国际化(i18n)完全指南:语言包结构、自定义加载与贡献新语言
发布时间:2026/9/12 14:09:59
listmonk 国际化i18n完全指南语言包结构、自定义加载与贡献新语言【免费下载链接】listmonkHigh performance, self-hosted, newsletter and mailing list manager with a modern dashboard. Single binary app.项目地址: https://gitcode.com/GitHub_Trending/li/listmonklistmonk 是一个高性能、自托管的邮件列表与新闻通讯管理器Go 后端 Vue 前端通过志愿者贡献的语言包实现了多语言界面。本篇指南以 i18n 官方文档 为主线深入讲解语言包的 JSON 结构、--i18n-dir加载机制、界面语言切换原理以及如何自定义语言包和向官方贡献一门新语言——掌握这些后你既可以随时为自己的实例定制中文等本地化文案也能参与开源社区的语言维护。语言包一个 JSON 文件即一门语言listmonk 的多语言支持建立在语言包language pack这一简单模型之上一门语言就是一个 JSON 文件内容是键key到翻译文本value的映射表。这些语言包由志愿者贡献随发行版内置仓库根目录的 i18n/ 目录即是全部内置语言包的存放位置。以英文基准包 i18n/en.json 为例其结构为扁平的 JSON 对象{ _.code: en, _.name: English (en), admin.errorMarshallingConfig: Error marshalling config: {error}, campaigns.confirmDelete: Delete {name}, analytics.title: Analytics, globals.terms.second: second }注意其中两个保留元数据键以_.开头_.code语言代码如en、zh-CN后端初始化时强制要求存在缺失会直接报错见 internal/i18n/i18n.go_.name语言的人类可读名称如English (en)用于管理界面中展示语言选项。普通键则按功能域分层命名analytics.*对应数据分析页、campaigns.*对应邮件活动页、globals.*为全局通用词月份、天数、按钮文案等。从源码结构看这套命名规范与前端 Vue 组件和后端 Go 错误信息的调用点一一对应方便翻译者按模块定位上下文。同一份 JSON前后端共用listmonk 的一个关键设计是同一份语言 JSON 同时服务于 Go 后端与 Vue 前端。后端实现位于 internal/i18n/i18n.go包注释明确说明它模拟了 vue-i18n 库的部分功能以便同一 JSON 语言映射可在 JS 前端与 Go 后端复用。Go 后端的翻译 APIinternal/i18n包提供四个核心翻译方法internal/i18n/i18n.go方法作用对应 vue-i18nT(key)返回键对应的翻译缺失时原样返回键名t()Ts(key, name, campaigns, ...)翻译并替换{name}这类占位参数参数以键值对形式成对传入个数必须为偶数t() 具名插值Tc(key, n)复数翻译约定值格式为Singular \| Pluraln 1时返回\|后的复数形式tc()其中Tc依赖的语言值格式在 getSingular/getPlural 中解析用竖线|分隔单复数例如second | seconds。Ts中的{param}占位符还会被 subAllParams 递归解析即参数值本身若含{key}会再次查表替换。语言加载流程后端启动时按先英文、后所选语言的顺序合并加载cmd/init.go默认以en为基底映射再把配置指定的语言加载到其上覆盖冲突键。这意味着自定义语言包中缺失的键会自动回退为英文不会出现界面空白或键名裸奔。该逻辑实现在 cmd/i18n.go 的getI18nLang中——它始终先读/i18n/en.json再读目标语言文件执行合并。前端方面Vue 应用挂载前会通过GET /api/lang/:lang拉取语言包frontend/src/main.js设置i18n.locale并调用setLocaleMessage注入全部翻译API 定义见 frontend/src/api/index.js路由注册见 cmd/handlers.go。该接口由 GetI18nLang 实现它用正则[^a-zA-Z_0-9\-]校验语言代码长度不超过 6、仅允许字母/数字/下划线/连字符杜绝了路径穿越等注入风险。界面语言从哪来界面默认语言由配置项app.lang决定配置结构见 cmd/init.go。在 Docker 部署中可通过环境变量LISTMONK_app__lang注入该变量随后经initI18n加载到后端并在服务器配置中下发给前端驱动 Vue-i18n 的 localecmd/main.go。内置语言与附加语言包截至本仓库版本i18n/ 目录内置了 40 余种语言包包括ar、bg、ca、cs、de、el、en、es、fr、he、hu、id、it、ja、ko、nl、pl、pt-BR、ru、tr、uk、vi、zh-CN、zh-TW等覆盖了全球主要语种。除内置包外社区还维护着附加语言包它们不随主发行版分发需要手动下载后通过--i18n-dir挂载。官方文档给出的示例语言说明Deutsch正式体使用正式称呼Sie的德语包适合面向正式商务场景的德语用户安装附加语言包的方式与下一节自定义语言完全相同本质上都是把语言 JSON 放进目录再用--i18n-dir告诉 listmonk。用--i18n-dir自定义或加载新语言无论是定制已有语言的措辞还是加载全新的语言包操作步骤完全一致将一个或多个.json语言文件放入某个目录启动 listmonk 时传入目录路径--i18n-dir/path/to/dir。命令行标志在 cmd/init.go 中注册f.String(i18n-dir, , (optional) path to directory with i18n language files)并在 cmd/main.go 传入initFS。底层加载机制initFS 揭示了--i18n-dir的实现细节listmonk 默认把资源文件嵌入二进制stuffbin 内嵌文件系统但当显式指定i18n-dir时会把你目录下的*.json文件映射到虚拟路径/i18n/*.jsoncmd/init.go并覆盖默认的内置语言文件。因此语言文件的文件名必须与语言代码一致例如zh-CN.json、de.json覆盖规则按文件同名生效——放一个en.json即可整体替换英文界面文案放一个zh-CN.json则可修正或增强既有简体中文翻译即便自定义包缺少某键加载逻辑仍会先用内置英文兜底再叠加你的覆盖cmd/i18n.go所以覆盖式定制非常安全不必担心遗漏。一个实用的定制场景运维团队可以把告警、按钮等高频文案统一改造成公司内部约定用语只需维护一个包含少量键的en.json其余全部走英文默认值。贡献一门新语言如果你希望把翻译成果回馈社区官方提供了两条路径基于官方在线编辑器的基础编辑方式以及基于 InLang 外部服务的协作方式。方式一官方 i18n 在线编辑器访问 listmonk 官方 i18n 页面https://listmonk.app/i18n点击Create a new language创建新语言或点击Load language载入既有语言进行修改在界面文本框中逐条翻译完成后点击Download raw JSON下载语言文件将文件作为 Pull Request 提交到仓库的i18n/目录对应本仓库的 i18n/。说明原文档给出的是 listmonk 官网托管地址。离线环境下直接以仓库内置的en.json为蓝本、手工补全_.code与_.name后按上述--i18n-dir方式加载验证再提交 PR效果等同。方式二InLang 外部协作服务访问 InLang 的 listmonk 编辑页https://inlang.com/editor/github.com/knadh/listmonk要保存修改并推送需要用 GitHub OAuth 登录并在界面上 fork 项目在输入框中翻译文本可利用筛选器只看需要翻译的条目完成后从界面推送修改点击Open a pull request跳转到 GitHub 填写 PR 说明。社区维护的辅助脚本仓库为语言包维护者提供了两个脚本scripts/scripts/refresh-i18n.sh以en.json为基准用jq把新增键合并进所有语言文件——新键取英文原文、旧翻译保留保证语言包与英文基准键同步scripts/translate-i18n.py调用 LLM APIgpt-4.1-mini自动翻译与英文完全相同的未译条目支持KEYS变量限定只翻译指定键输出时按sort_keys排序、ensure_asciiFalse保留非 ASCII 字符适合快速启动一门新语言的初稿。这两个脚本体现了官方维护流程英文是键的唯一基准各语言包通过脚本与基准持续对齐。贡献新语言时先运行refresh-i18n.sh同步键再逐条翻译是最贴合上游工作流的方式。语言包的工程约束速查从源码中可以提炼出几条硬性约束自定义语言包时务必遵守必须包含_.code与_.name缺失任一键i18n.New直接返回错误internal/i18n/i18n.go其中_.code若对应文件缺失启动时视情况告警或中止cmd/init.go。语言代码字符集受限仅允许[a-zA-Z_0-9\-]长度不超过 6cmd/i18n.go因此zh-CN、pt-BR这类带连字符的代码可用含空格或点号的代码会被拒绝。文件名 语言代码--i18n-dir目录下的 JSON 文件名必须与_.code一致才能被正确路由和加载。值内占位符用{key}花括号语法参数化文案如campaigns.confirmDelete: Delete {name}由Ts或前端 vue-i18n 插值替换复数形式用Singular | Plural竖线分隔。加载顺序为英文兜底 覆盖自定义包不必翻译全部键缺失部分自动回退英文。小结listmonk 的 i18n 设计以一份 JSON、前后端共用为核心Go 侧用internal/i18n包解析并做兜底合并Vue 侧通过/api/lang/:lang拉取同一份数据交给 vue-i18n 渲染--i18n-dir是接入自定义与附加语言包的统一入口配合英文兜底机制让按需定制界面文案变得异常轻量。无论是为团队实例定制中文术语、修复某个翻译还是向社区贡献一门全新语言你都可以直接参考仓库内置的 40 余份语言包与两个维护脚本快速上手。【免费下载链接】listmonkHigh performance, self-hosted, newsletter and mailing list manager with a modern dashboard. Single binary app.项目地址: https://gitcode.com/GitHub_Trending/li/listmonk创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考