尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Joplin 本地化(Localisation)指南:应用翻译与文档翻译的完整工作流

Joplin 本地化(Localisation)指南:应用翻译与文档翻译的完整工作流 Joplin 本地化Localisation指南应用翻译与文档翻译的完整工作流【免费下载链接】joplinJoplin - the privacy-focused note taking app with sync capabilities for Windows, macOS, Linux, Android and iOS.项目地址: https://gitcode.com/GitHub_Trending/jo/joplin本篇指南以 Joplin 仓库中的 readme/dev/localisation.md 为骨架系统讲解 Joplin 的本地化体系如何为桌面端、移动端和终端三款应用贡献新的语言翻译如何通过 Crowdin 参与官方文档翻译并结合仓库源码packages/tools/build-translation.ts、packages/lib/locale.ts、crowdin.yml等深入剖析其底层的 gettext 提取、.po合并与运行时加载机制。读完本文你将掌握 Joplin 翻译的完整贡献流程以及其本地化管线从源码字符串到最终界面的全链路原理。一、Joplin 本地化体系概览Joplin 的本地化工作分两条独立管线应用翻译面向桌面端app-desktop、移动端app-mobile和终端app-cli三款应用的用户界面字符串。源码中的字符串通过 gettext 工具链提取到joplin.pot模板再由社区译者翻译为各语言的.po文件最终编译为运行时加载的 JSON 词典。文档翻译面向readme/目录下的官方文档托管在 Crowdin 平台项目joplin-website配置见 crowdin.yml。一个值得注意的设计是一份应用翻译文件同时作用于桌面、移动、终端三款应用。由于三端共用packages/lib中的字符串提取与加载机制参见 packages/lib/locale.ts 与 packages/lib/locales/index.js译者只需维护一份.po即可覆盖全部客户端。二、贡献新的应用翻译从零开始如果你希望为 Joplin 添加一门全新的语言官方流程相当直接只需四步1. 安装翻译编辑器 Poedit下载并安装 Poedit——这是一款跨平台的 gettext.po/.pot文件可视化编辑器支持 Windows、macOS 与 Linux能够以友好的界面展示待翻译条目、模糊标记fuzzy与复数形式。2. 获取待翻译的模板文件下载当前仓库的翻译模板 packages/tools/locales/joplin.pot。该文件是英文原文 → 空翻译的 gettext 模板包含从源码中提取的全部可翻译字符串每个条目都带#:注释标明出处例如#: packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx:634 msgid - Camera: to allow taking a picture and attaching it to a note. msgstr 这里msgid是英文原文msgstr是待填写的译文#:后的路径如packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx:634指明该字符串在源码中的引用位置方便译者理解上下文。3. 在 Poedit 中配置语言并开始翻译在 Poedit 中打开joplin.pot后进入Catalog目录菜单 → Configuration配置将Country国家与Language语言改为你自己的国家和语言。此后即可逐条翻译文件内容。以仓库中 packages/tools/locales/zh_CN.po 为例其文件头部展示了译者信息与语言元数据的规范格式Last-Translator: wh201906 wh201906yandex.com\n Language-Team: zh_CN clstycelestialy.top\n Language: zh_CN\n Plural-Forms: nplurals1; plural0;\n条目翻译示例英文原文与简体中文译文一一对应msgid - Location: to allow attaching geo-location information to a note. msgstr - 定位权限允许将地理位置信息添加到一条笔记中。4. 提交 Pull Request翻译完成后将.po文件加入 Pull Request 并提交到仓库即可。这份翻译将自动适用于桌面、移动和终端三款应用。更新已有翻译若要更新某门已有语言的翻译流程与新增翻译相同但无需下载joplin.pot模板而是从下方的翻译列表中下载对应语言的.po文件例如 packages/tools/locales/fr_FR.po、packages/tools/locales/zh_CN.po进行增量翻译。三、翻译文件的三种形态与格式规范Joplin 应用翻译在仓库中呈现为层层递进的三种形态理解它们有助于正确贡献与排查问题形态路径作用.pot模板packages/tools/locales/joplin.pot从源码自动提取的全部英文原文作为翻译基准.po翻译文件packages/tools/locales/如ar.po、zh_CN.po等 43 个译者编辑的实体每个条目含原文与译文.json运行时词典packages/lib/locales/如zh_CN.json编译产物应用运行时实际加载的词典从源码结构看.po→.json的转换由 packages/tools/build-translation.ts 中的buildLocale()完成先用gettext-parser解析.po文件parsePoFile见 packages/tools/utils/translation.ts再经parseTranslations()转换为{ 英文原文: [译文] }键值映射并序列化为 JSON。需要特别指出的是parseTranslations()的两个关键过滤规则packages/tools/utils/translation.tsfuzzy模糊翻译会被丢弃带有fuzzy标志的条目通常是原文变更后由工具自动标记、尚未经人工确认的翻译不会进入 JSON 词典运行时回退显示英文原文未翻译条目不出现在结果中若某条msgstr为空同样不进入词典界面将显示英文。复数形式Plural-Forms的处理不同语言对复数有不同规则Joplin 通过.po头部的Plural-Forms声明并在运行时解析。构建时 build-translation.ts 会把Plural-Forms表达式编译成pluralForms: function(n) {...}注入 packages/lib/locales/index.js 的stats表运行时则由 packages/lib/locale.ts 的getPluralFunction()按当前语言取用。例如中文nplurals1; plural0;表示只有单数形态而俄语等多形态语言则对应更复杂的表达式。四、构建与自动化翻译管线源码级剖析Joplin 的翻译构建由 packages/tools/build-translation.ts 驱动这是一套几乎全自动的流水线其依赖与步骤值得仔细说明。环境依赖脚本头部注释明确列出了系统级依赖packages/tools/build-translation.tsgettext工具集提供msgmerge等命令且要求 gettext v21 及以上——旧版本在解析 JavaScript 模板字符串时存在 bug会导致丢失翻译translate-toolkit提供pocount用于统计翻译进度百分比另外packages/tools/package.json 中声明了 npm 依赖gettext-extractor源码字符串提取与gettext-parser.po解析。核心流程步骤扫描源码文件createPotFile()用find遍历仓库中所有.js/.ts/.tsx文件排除测试、构建产物、node_modules 等见 build-translation.ts 中的excludedDirs列表。当同名.js与.ts并存时只保留.ts因为.js通常是编译产物。提取可翻译字符串使用gettext-extractor的JsExtractors.callExpression匹配源码中的_(...)与_n(..., ...)调用build-translation.ts将第一个参数作为原文写入joplin.pot。注释中还解释了**刻意不写入 msgctxt上下文**的原因如果为字符串附加了会随调用处变化的上下文一旦调用参数改变对应条目就会被标记为 fuzzy 而需要重新翻译不写上下文则可避免这种不必要的连锁重译。官方此前曾使用xgettext但它对 TypeScript 支持不完整、完全不支持.tsx且 TS 编译器会把_(...)编译为(0,locale._)(...)导致漏检因此改用了gettext-extractor。字符串增删保护重新生成joplin.pot后脚本会比较新旧字符串集合。若检测到删除的字符串达到 5 条及以上会中止构建build-translation.ts——这是为了防止源码里大量字符串意外消失这类 bug 悄悄清空翻译。可用--skip-missing-strings-check标志强制跳过或用--missing-strings-check-only仅做检查。合并模板到各语言对每个非默认语言调用msgmerge -U xx.po joplin.potmergePotToPo见 packages/tools/utils/translation.ts把新增的英文原文合并进各语言文件同时移除POT-Creation-Date/PO-Revision-Date头removePoHeaderDate保证每次构建生成的文件内容确定性一致。编译 JSON 并生成注册表逐一将.po转为.json用pocount统计各语言完成百分比最后生成 packages/lib/locales/index.js含locales注册表与stats统计表。回写文档表格updateReadmeWithStats()会把各语言的国旗、名称、文件、最后译者与完成度渲染成 Markdown 表格插入 readme/dev/localisation.md 中!-- LOCALE-TABLE-AUTO-GENERATED --标记之间。这意味着你看到的翻译列表完全由构建脚本自动生成无需手工维护。五、运行时如何加载翻译locale.ts 机制理解了构建管线再看应用运行时如何消费这些 JSON 词典。核心实现位于 packages/lib/locale.ts三端应用均通过import { _ } from joplin/lib/locale使用例如 packages/app-cli/app/app.ts。关键函数与机制_(s, ...args)按当前语言查词典取译文支持sprintf风格的%s参数替换locale.ts。若词典中无对应条目则回退显示英文原文并在参数替换失败时返回带(Translation error: ...)的提示串便于定位。_n(singular, plural, n, ...args)复数形式选择。对en_GB/en_US按n 1简单判断其他语言则调用getPluralFunction()得到按Plural-Forms表达式编译的选择函数再取对应的复数形态locale.ts。setLocale(canonicalName)与closestSupportedLocale()设置当前语言时会做模糊匹配——把系统常见的zh-TW风格连字符规范为zh_TW下划线格式找不到完全匹配时回退到同语言的第一个变体再不行则回退默认语言en_GBlocale.ts。supportedLocales()直接require(./locales/index.js)读取构建生成的注册表这就是 packages/lib/locales/index.js 中 40 条locales[xx] require(./xx.json)声明被逐一加载的入口locale.ts。由此可见一条完整的翻译链路是源码_(...)调用 → gettext-extractor 提取 → joplin.pot → 译者用 Poedit 填写 .po → msgmerge 合并 → buildLocale 生成 .json → index.js 注册 → 运行时_()查表渲染。六、翻译文档Crowdin 协作流程除了应用界面Joplin 的官方文档readme/目录下的全部 Markdown也支持多语言托管在 Crowdin 平台的joplin-website项目上。参与方式很简单注册一个 Crowdin 账号进入该项目即可开始逐段翻译。仓库根目录的 crowdin.yml 揭示了文档翻译的完整配置project_id: 624298 api_token_env: CROWDIN_PERSONAL_TOKEN preserve_hierarchy: true files: - source: /readme/**/* translation: /readme/i18n/%two_letters_code%/docusaurus-plugin-content-docs/current/**/%original_file_name% ignore: - /**/*.jpg - /**/*.json - /**/*.png - /**/*.yml - /readme/_i18n - /readme/about/changelog - /readme/about/stats.md - /readme/api - /readme/cla.md - /readme/connection_check.md - /readme/dev - /readme/i18n - /readme/licenses.md - /readme/news - /readme/privacy.md几个要点source: /readme/**/*表示翻译源是整个文档目录翻译输出到/readme/i18n/语言码/...路径保持目录层级preserve_hierarchy: trueignore列表排除了图片、JSON 配置、变更日志、统计页等无需或不宜翻译的内容——值得注意的是/readme/dev整个目录被排除即开发者文档不参与 Crowdin 翻译api_token_env表明 CI 同步通过环境变量CROWDIN_PERSONAL_TOKEN提供认证。如果希望新增一门文档语言或遇到任何其他问题官方建议在论坛或 GitHub 上联系维护者。七、当前支持的语言一览下表汇总了当前仓库 packages/tools/locales/ 中收录的应用翻译语言名称与完成度以 readme/dev/localisation.md 自动生成的表格为准Po 文件路径已转换为仓库内相对路径便于直接查看语言Po 文件完成度Arabicar.po47%Basqueeu.po12%Norwegian Bokmålnb_NO.po47%Bosnianbs_BA.po30%Bulgarianbg_BG.po53%Catalanca.po81%Croatianhr_HR.po79%Czechcs_CZ.po52%Danishda_DK.po81%Germande_DE.po81%Estonianet_EE.po23%English (UK)en_GB.po100%English (US)en_US.po100%Spanishes_ES.po81%Esperantoeo.po13%Finnishfi_FI.po81%Frenchfr_FR.po100%Galiciangl_ES.po73%Indonesianid_ID.po81%Italianit_IT.po81%Hungarianhu_HU.po100%Dutch (Belgium)nl_BE.po69%Dutch (Netherlands)nl_NL.po81%Persianfa.po81%Polishpl_PL.po75%Portuguese (Brazil)pt_BR.po81%Portuguese (Portugal)pt_PT.po64%Romanian (Moldova)ro_MD.po81%Romanian (Romania)ro_RO.po81%Sloveniansl_SI.po42%Slovaksk_SK.po81%Swedishsv.po81%Thaith_TH.po19%Vietnamesevi.po41%Turkishtr_TR.po81%Ukrainianuk_UA.po68%Greekel_GR.po70%Russianru_RU.po81%Serbiansr_RS.po34%中文简体zh_CN.po80%中文繁體zh_TW.po81%日本語ja_JP.po81%한국어ko.po59%几点观察与提醒英文en_GB/en_US与法文、匈牙利文已达到 100% 完成度其中en_US在构建脚本中被强制视为 100%见 build-translation.ts 的isAlways100逻辑完成度数据由pocount依据.po文件实时统计会随版本迭代而变化因此上表仅为当前仓库快照表格由构建脚本自动写入文档的!-- LOCALE-TABLE-AUTO-GENERATED --标记区域人工不应直接编辑该区域修改应发生在.po文件层面。八、贡献翻译的注意事项结合源码与官方文档贡献翻译时有几点实践经验值得遵循保持.po格式合法Poedit 会自动维护格式但若手工编辑务必保证msgid/msgstr配对完整、转义正确否则gettext-parser解析会失败构建流程将中断。不要改动joplin.pot该模板由构建脚本自动生成任何手工修改都会在下次构建时被覆盖。警惕字符串删除保护如果你发现构建报N strings have been deleted - aborting说明源码侧可能误删了大量字符串需先核对源码而非强行跳过检查。模糊条目不会被加载Poedit 中显示为需要审阅fuzzy的条目即使填写了译文也不会进入运行时词典提交前应确认所有模糊条目已审阅通过。三端共享一份翻译桌面、移动、终端的界面字符串统一维护提交到正确语言的.po文件即可覆盖全部平台。九、进一步探索若希望深入本地化体系的实现细节可在当前仓库中继续阅读构建入口与完整流程packages/tools/build-translation.tsgettext 工具封装msgmerge、头信息清理、解析与 fuzzy 过滤packages/tools/utils/translation.ts运行时语言核心_、_n、语言匹配、复数函数packages/lib/locale.ts运行时词典注册表packages/lib/locales/index.js文档翻译配置crowdin.yml翻译模板与全部语言文件packages/tools/locales/【免费下载链接】joplinJoplin - the privacy-focused note taking app with sync capabilities for Windows, macOS, Linux, Android and iOS.项目地址: https://gitcode.com/GitHub_Trending/jo/joplin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表