2026/9/21 16:13:08

PeerTube 多语言翻译指南:基于 Weblate 的协作流程、翻译文件体系与规范要点

PeerTube 多语言翻译指南:基于 Weblate 的协作流程、翻译文件体系与规范要点 音视频视频后端前端【免费下载链接】PeerTubeActivityPub-federated video streaming platform using P2P directly in your web browser项目地址https://gitcode.com/gh_mirrors/pe/PeerTube点击查看免费下载PeerTube 是一个基于 ActivityPub 联邦协议的分布式视频平台其界面、播放器与服务器端文案全部支持多语言。本文以官方翻译文档 support/doc/translation.md 为主线结合仓库中的翻译文件与脚本实现client/src/locale、scripts/i18n/update.sh 等完整讲解译者如何加入社区、四类翻译文件的职责划分、翻译时必须遵守的占位标签与单复数规则并延伸到仓库侧生成、合并翻译以及新增语言支持的完整流水线帮助你快速上手参与 PeerTube 的本地化工作也能作为维护者理解翻译工程化细节的参考。翻译工作流概览为什么必须通过 Weblate 协作PeerTube 的翻译平台是Weblate这是一条硬性约束请勿直接从 Git 仓库编辑翻译文件一切翻译都必须通过 Weblate 完成。原因在于翻译文件由自动化流水线生成与合并直接在仓库中修改会与上游模板冲突也会在i18n:update执行时被覆盖。完整的翻译生命周期如下译者或机器翻译在 Weblate 平台提交译文翻译会被定期手动拉取fetch并合并进 PeerTube 主仓库合并后的翻译在下一个官方版本中向所有实例公开如果想提前看到未发布的新翻译官方维护了一个每晚自动更新的预览实例持续部署最新的 PeerTube 变更可以在正式发布前检查自己的译文效果。如果你在平台上找不到自己的语言可以直接在 Weblate 界面中新增该语言当你认为该语言的翻译量已经足够时再去提交 issue请维护者将新语言正式纳入 PeerTube 的语言列表。参与翻译的完整步骤How to官方文档给出的译者操作流程分四步注册账号在 Weblate 平台由 Framasoft 托管注册新账号验证邮箱查收注册邮件并点击验证链接设置账号设置密码保持当前密码字段为空并完善账号信息选择要翻译的项目与语言翻译 PeerTube网页端进入 PeerTube 项目主页翻译 PeerTube移动端应用进入 PeerTube App 项目主页然后选择具体的翻译文件和目标语言开始翻译。在 Weblate 界面中每个语言都对应一组翻译文件详见下一节你可以按文件逐个推进也可以从完成度最低、影响最大的文件开始。四类翻译文件的职责划分PeerTube 的翻译并非单一文件而是按运行环境划分为4 个翻译文件它们分别承载不同的字符串职责互不重叠文件内容存放位置仓库侧angular客户端Angular Web 应用界面字符串格式为 XLIFFclient/src/locale/angular.*.xlfplayer播放器字符串格式为 JSONclient/src/locale/player.*.jsonserver服务器端公共字符串客户端可 JSON 方式获取避免各自重复翻译通用词ISO 639 语言名、隐私级别、许可证等client/src/locale/server.*.jsonserver-internal服务器内部字符串用于 REST API 响应或邮件模板server/locales/en-US/translation.jsonplayer 文件的特别之处VideoJS 源生字符串player文件里的大部分字符串来自VideoJS播放器库。翻译时可以参照 VideoJS 官方语言文件作为参考仓库中已内置了英文基准文件 client/src/locale/videojs.en-US.jsonPeerTube 会在其基础上叠加自己的播放器定制文案。从 scripts/i18n/create-custom-files.ts 的实现可以看到player.en-US.json正是由videojs.en-US.json合并 PeerTube 自有的播放器字符串画质、倍速、P2P 统计、剧场模式、隐藏字幕、下一个视频等生成的const videojs readJsonSync(join(root(), client, src, locale, videojs.en-US.json)) const playerKeys { Quality: Quality, Auto: Auto, Speed: Speed, // ... } Object.assign(playerKeys, videojs)server 文件的生成机制常量自动汇聚server文件比较特殊——它的基础字符串来自 PeerTube 后端定义的各种枚举常量而不是人工维护的清单。同一脚本 scripts/i18n/create-custom-files.ts 会把视频分类、许可证、隐私级别、视频状态、导入状态、播放列表隐私、用户角色标签、举报状态等常量定义于 server/core/initializers/constants.ts以及完整的ISO 639 语言名全部汇聚进serverKeysObject.values(VIDEO_CATEGORIES) .concat(Object.values(VIDEO_LICENCES)) .concat(Object.values(VIDEO_PRIVACIES)) .concat(Object.values(VIDEO_STATES)) // ... .forEach(v { serverKeys[v] v })这意味着只要后端的常量如新增一种视频分类变化重新运行脚本即可自动生成新的待翻译 key并合并进各语言的server.*.json译者在 Weblate 上立刻就能看到新增条目。翻译规范一特殊标签占位符不可翻译Angular 的 XLIFF 翻译文件里带x ... /形式的标签是代码占位符interpolation 插值它们会被 Angular 运行时替换为真实的动态值如视频发布时间、观看次数。翻译时必须原样保留这些标签只翻译标签外的自然语言。以官方文档给出的示例为例英文原文x idINTERPOLATION equiv-text{{ video.publishedAt | myFromNow }}/ - x idINTERPOLATION_1 equiv-text{{ video.views | myNumberFormatter }}/ views法语译文应为views翻译为vues标签原样不动x idINTERPOLATION equiv-text{{ video.publishedAt | myFromNow }}/ - x idINTERPOLATION_1 equiv-text{{ video.views | myNumberFormatter }}/ vuesequiv-text属性里的 Angular 表达式如{{ video.publishedAt | myFromNow }}同样不要改动否则页面渲染时插值会失效。这类占位标签在 client/src/locale/angular.en-US.xlf 中大量存在是翻译时最容易出错、也最需要留意的点。翻译规范二单复数ICU Plural规则XLIFF 中的单复数使用 ICU 复数语法{VAR_PLURAL, plural, ...}表示。翻译时只需要翻译{和}内部的文案且绝对不能翻译关键词other它是 ICU 语法的关键字必须保留原文。官方示例英文原文{VAR_PLURAL, plural, 0 {No videos} 1 {1 video} other {x idINTERPOLATION equiv-text{{ playlist.videosLength }}/ videos} }法语译文保留other与占位标签{VAR_PLURAL, plural, 0 {Aucune vidéo} 1 {1 vidéo} other {x idINTERPOLATION equiv-text{{ playlist.videosLength }}/ vidéos} }需要注意的是不同语言的复数分类数量不同英语只有单数/复数而法语、俄语、阿拉伯语等语言有更复杂的复数形态零、一、二、少量、多数等。Weblate 会根据目标语言的复数规则展示对应数量的分支供你填写务必把每个分支都翻译到位避免界面中出现裸奔的英文词。仓库侧i18n 流水线如何生成与合并翻译翻译文件虽然是从 Weblate 拉取但仓库侧的生成与合并逻辑才是翻译工程的底座。核心入口是根目录 package.json 中的脚本npm run i18n:update→ 执行 scripts/i18n/update.shnpm run i18n:create-custom-files→ 执行 scripts/i18n/create-custom-files.tsupdate.sh的完整执行链如下# 1. 拉取 Weblate 的翻译提交并合并 git fetch weblate git merge weblate/develop # 2. 构建 embed 播放器保证提取的字符串与产物一致 npm run build:embed cd client # 3. 用 Angular 的 extract-i18n 重新生成英文基准文件 angular.xlf npm run ng -- extract-i18n --out-file src/locale/angular.xlf # 4. 找出所有已有语言用 xliffmerge 把新增 key 合并进各语言文件 locales$(find src/locale -type f | grep -e angular\.[^.]\\.xlf | ...) ./node_modules/.bin/xliffmerge -p ./.xliffmerge.json $locales # 5. 格式化所有 XLIFF for file in angular.*.xlf; do xmllint --format $file $file.tmp mv $file.tmp $file; done cd ../ # 6. 生成 player/server 基础 JSON 并合并到各语言文件 npm run i18n:create-custom-files # 7. 用 i18next-cli 从服务器源码提取内部字符串REST API / 邮件 ./node_modules/.bin/i18next-cli -c server/.i18next.config.ts extractxliffmerge 的配置Angular XLIFF 的合并参数在 client/.xliffmerge.json 中定义源目录与生成目录均为src/locale基础文件名为angular默认语言为en-US{ xliffmergeOptions: { i18nFormat: xlf, srcDir: src/locale, genDir: src/locale, i18nBaseFile: angular, defaultLanguage: en-US } }服务器内部字符串的提取server-internal文件即 server/locales/en-US/translation.json由 server/.i18next.config.ts 驱动 i18next-cli 生成。该配置值得注意的几点locales直接引用packages/core-utils中的I18N_LOCALES列表保证与客户端语言清单同步内置了一个handlebars 插件通过正则/\{\{t\s[]\s?.*\}\}/g从server/**/*.hbs邮件模板中提取{{t key}}形式的 key设置keySeparator: false、nsSeparator: false避免 key 中的.被错误拆分为命名空间。新增一种语言的完整操作清单当社区在 Weblate 上完成了新语言的翻译后维护者需要按 support/doc/development/localization.md 中的清单把新语言正式接入 PeerTube将新语言加入 packages/core-utils/src/i18n/i18n.ts 的I18N_LOCALES映射按字母序排列将新语言加入 client/angular.json 的构建配置锁定 Weblate 项目避免合并期间产生冲突运行npm run i18n:update重新生成并合并所有翻译文件构建应用并验证新语言在界面中正常工作。从 packages/core-utils/src/i18n/i18n.ts 可以看到PeerTube 目前内置了en-US、ar、ca-ES、de-DE、fr-FR、ja-JP、zh-Hans-CN、zh-Hant-TW等 40 余种语言并维护了一张语言别名表如zh-CN→zh-Hans-CN、pt→pt-BR用于在 HTTP Accept-Language 头与内部 locale 之间做兼容转换const I18N_LOCALE_ALIAS { en: en-US, fr: fr-FR, zh-CN: zh-Hans-CN, zh-TW: zh-Hant-TW, // ... }I18N_LOCALES中en-US必须排在最前官方注释说明这是为了在请求未携带 Accept-Language 头时避免express acceptLanguages函数出现歧义。这些细节决定了翻译文件里有什么与用户实际看到什么之间的映射关系也是新增语言时必须同步维护的地方。翻译节奏与发布周期回到工作流的闭环Weblate 上的翻译提交是持续发生的而 PeerTube 仓库会手动拉取并合并翻译合并后的成果将在下一个官方发布版本中对外公开。维护者执行git fetch weblate git merge weblate/develop即完成一次翻译同步而每次i18n:update都会重新生成基准文件、合并新 key保证 Weblate 上的译者永远基于最新的字符串工作。对于想提前验收译文的译者官方提供了每晚更新的预览实例可查看尚未进入正式版本的翻译效果确认无误后你的译文会在下一个版本中随 PeerTube 一起发布被全球所有联邦实例加载使用。总结参与 PeerTube 翻译的核心要点可以归纳为三句话一切翻译通过 Weblate不直接改 Git 文件四类文件angular / player / server / server-internal各司其职占位标签x ... /与关键字other必须原样保留翻译的生成、合并与发布由仓库内的 i18n 脚本流水线自动化完成。无论是想为界面贡献一句译文还是作为实例维护者排查多语言问题理解这套从 Weblate 到 scripts/i18n/update.sh、再到 client/src/locale 与 server/locales 的完整链路都会让你的工作事半功倍。赞分享音视频视频后端前端【免费下载链接】PeerTubeActivityPub-federated video streaming platform using P2P directly in your web browser项目地址https://gitcode.com/gh_mirrors/pe/PeerTube点击查看免费下载相关推荐ent 文档多语言翻译指南基于 Crowdin 的协作翻译与发布流程ent 文档多语言翻译指南基于 Crowdin 的协作翻译与发布流程 ent 官方通过 Crowdin 平台发起了文档翻译计划目标是让官网全部文档以中文、日后端ORM代码生成Karakeep国际化Weblate多语言翻译的协作流程Karakeep国际化Weblate多语言翻译的协作流程 Karakeep是一款强大的自托管书签管理应用支持链接、笔记和图片的全方位收藏并具备AI自动标签后端前端移动开发AI 应用知识管理全文检索MCP 服务FreeShow多语言支持完整指南为全球演示创建专业本地化体验FreeShow多语言支持完整指南为全球演示创建专业本地化体验 想要为国际观众制作专业演示吗FreeShow作为一款免费开源的演示软件通过强大的多语言支持桌面应用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考