openedx-platform 翻译文件标准化决策:为什么只保留 django.po 与 djangojs.po 两个资源文件
【免费下载链接】openedx-platformThe Open edX LMS & Studio, powering education sites around the world!项目地址: https://gitcode.com/GitHub_Trending/ed/openedx-platform
本文以 Open edX 的架构决策记录《Standardize django.po and djangojs.po files》为主线,讲清 openedx-platform 国际化(i18n)资源文件从"十余个分片"回归"两个标准文件"的决策背景、取舍依据与被否决的方案;并结合仓库中真实的 i18n 配置、Makefile 目标与测试翻译数据,梳理当前翻译提取(extract)、拉取(pull)与编译(compile)的完整链路,帮助你在维护或二次开发 openedx-platform 时准确理解其国际化工作流。
1. 决策背景:为什么曾经要把翻译拆成 11 个文件
该决策记录的状态为Accepted(已采纳)。其背景(Context)部分给出了当时的四个关键事实:
- edx-platform 曾把翻译拆分为
mako-studio.po、django-partial.po以及另外 9 个文件,合计 11 个资源文件。拆分的初衷是让 LMS(学习者端)可以支持比 CMS(Studio,教师端)更多的语言——新语言只需翻译 LMS 相关字符串,不必同步翻译 Studio 字符串。 - 拆分手段是
edx-i18n-tools提供的i18n_tools segment命令,目标同样是降低翻译者的认知负担。 - 在从 Transifex 拉取翻译或切版(release cut)时,这些分片最终会合并回两个文件:
django.po和djangojs.po——因为 Django 运行时只认这两个文件。 - 随着 Translation Infrastructure 更新(对应 Open edX 社区提案 OEP-58)落地,所有翻译文件迁移到统一的 openedx-translations Transifex 项目中,openedx-platform 等仓库改为通过openedx-atlas命令行工具拉取翻译。
- 在新的
extract-translation-source-files.ymlGitHub 工作流(位于 openedx-translations 仓库)中,从 edx-platform 提取翻译源文件需要若干特殊步骤,被认为冗余且应当简化。
"拆成 11 个用于协作、最后又合并回 2 个用于运行"的流程,正是本次决策要消除的复杂度。
2. 仓库中的实证:拆分配置就写在 conf/locale/config.yaml
决策文档中提到的分片机制,在当前仓库 conf/locale/config.yaml 中可以直接看到。这份文件是i18n_tool(来自 edx-i18n-tools,requirements 中锁定为 2.0.0)的工作流配置,包含几个与决策强相关的部分:
2.1 语言与测试语言
locales: - en # English - Source Language # The locales used for fake-accented English, for testing. dummy_locales: - eo - rtl # Fake testing language for Arabic其中eo(世界语)是"伪口音英语"测试语言。仓库中 conf/locale/eo/LC_MESSAGES 目录下确实存放着django.po、djangojs.po及其编译产物.mo,这正是 Makefile 中清理逻辑特意保留的对象(见第 4 节)。
2.2 忽略目录与第三方提取源
配置中的ignore_dirs列出了不参与字符串提取的目录,包括*/migrations、*/envs、node_modules、conf、docs、各类资源目录(*/images、*/sass等)、测试目录(common/test、*/tests)以及自动生成的 JS 翻译产物lms/static/js/i18n、cms/static/js/i18n等。third_party字段声明了额外提取字符串的第三方应用:
third_party: - wiki注释明确要求:新增此类应用时,必须同步更新本文件的generate_merge合并列表和 Makefile 的extract_translations目标,否则字符串无法进入翻译平台。wiki 应用的字符串提取依赖独立的 Babel 配置文件 conf/locale/babel_third_party.cfg(提取 Python、Django 模板与 ReactJS 三种源),另有 conf/locale/babel_mako.cfg(Mako 模板、mustache 与邮件模板,覆盖cms/、lms/、common/、openedx/**、themes/等目录树)与 conf/locale/babel_underscore.cfg(Underscore.js 模板,注册自定义提取器enmerkar_underscore:extract)。
2.3 segment:决策文档所指的"分片"逻辑
配置中的segment部分就是决策 Context 里所说的i18n_tools segment分片规则。其格式为"源 po 文件 → 派生 po 文件 → 按路径模式隔离的字符串":
segment: django-partial.po: # This .po file.. django-studio.po: # produces this .po file.. - cms/* # by segregating strings from these files. # Anything that doesn't match a pattern stays in the original file. djangojs-partial.po: djangojs-studio.po: - cms/* mako.po: mako-studio.po: - cms/* underscore.po: underscore-studio.po: - cms/*即从 Django(Python)、Django JS、Mako 模板、Underscore 模板四个来源中,把cms/*(Studio)路径产生的字符串分别隔离进django-studio.po、djangojs-studio.po、mako-studio.po、underscore-studio.po,其余字符串留在原始文件中。这正是"LMS 先行支持新语言、Studio 可滞后翻译"思路的实现载体。
2.4 generate_merge:分片如何合回两个运行文件
generate_merge定义了生成步骤的合并规则,也解释了为什么 eo 测试翻译的 django.po 文件头 中会连续出现django-partial.po、django-studio.po、mako.po、mako-studio.po、wiki.po五个来源标记:
generate_merge: django.po: - django-partial.po - django-studio.po - mako.po - mako-studio.po - wiki.po djangojs.po: - djangojs-partial.po - djangojs-studio.po - djangojs-account-settings-view.po - underscore.po - underscore-studio.po即:django.po由 5 个分片合并而来,djangojs.po由 5 个分片合并而来。拆分用于协作、合并用于运行——两头都要维护,这正是决策要简化的痛点。
3. 决策内容:只使用 django.po 与 djangojs.po 两个文件
决策记录的结论非常明确:edX Platform 只向 openedx-translations Transifex 项目推送两个文件——django.po和djangojs.po(原文此处有笔误写为djangojs.)。
其后果(Consequences)分析如下:
Pros(收益)
- 翻译者面对 edx-platform 仓库只需关注 2 个资源,而不是 11 个;
- openedx-translations 仓库中的
extract-translation-source-files.yml工作流里针对 edx-platform 的提取脚本得以简化; - 切版流程被简化——翻译合并(merger)步骤被整个移除;
- 翻译者对 master(latest)与命名版本(named releases)只需一条工作流;
- Build Test Release 工作组与 Transifex 工作组两侧的工作量都得到减轻。
Cons(代价)
- 翻译者更难聚焦学习者面向(learner-facing)文案、更难把教师面向(educator-facing)文案降级处理——因为 LMS 与 Studio 的字符串将混在同一个文件中。
这是一次典型的"以协作粒度换流程复杂度"的取舍:社区反馈(见决策引用的 PR 讨论)表明,按文件拆分聚焦这一特性在 Open edX 社区中使用频率较低,因此流程简化的收益更大。
4. 被否决的替代方案:四文件合并方案
决策记录详细评估并否决了"合并为四个文件"的替代方案(Combine into four files)。该方案试图在简化与聚焦之间折中:保留"拆分以便翻译者优先处理 learner-facing 文案"的原始意图,同时让翻译者不必再面对wiki.po、mako.po、django-partial.po这类技术分片名。
四个目标文件为:
platform.po(LMS 的 Django 字符串)platform-js.po(LMS 的 JS 字符串)studio.po(Studio 的 Django 字符串)studio-js.po(Studio 的 JS 字符串)
方案要求新增两个配置文件与对应的 Makefile 改动。用于提取侧的config.extract-oep58.yaml(当环境变量OPENEDX_COMBINE_FILES启用时,由make extract_translations使用):
# config.extract-oep58.yaml # This file is used by the ``make extract_translations`` when # the OPENEDX_COMBINE_FILES environment variable is enabled. generate_merge: platform.po: - django-partial.po - mako.po - wiki.po platform-js.po: - djangojs-partial.po - djangojs-account-settings-view.po - underscore.po studio.po: - django-studio.po - mako-studio.po studio-js.po: - djangojs-studio.po - underscore-studio.po配套 Makefile 改动:
extract_translations: ## extract localizable strings from sources i18n_tool extract -v if [ -z "$$OPENEDX_COMBINE_FILES" ]; then \ i18n_tool generate --config=config.extract-oep58.yaml --verbose 1; fi用于拉取侧的config.pull-oep58.yaml(当环境变量OPENEDX_ATLAS_PULL启用时,由make pull_translations使用)负责把四个文件再合回 Django 可运行的两个文件:
# config.pull-oep58.yaml # This file is used by the ``make pull_translations`` when # the OPENEDX_ATLAS_PULL environment variable is enabled. generate_merge: django.po: - platform.po - studio.po djangojs.po: - platform-js.po - studio-js.popull_translations: ## extract localizable strings from sources if [ -z "$$OPENEDX_ATLAS_PULL" ]; then \ atlas pull translations/edx-platform/conf/locale i18n_tool --config=config.pull-oep58.yaml generate --verbose 1; fi否决理由:该方案引入了多轮合并与拆分步骤,开发者需要同时理解两套配置、两个环境变量开关,复杂度显著上升;而 PR 中的社区反馈表明"拆分资源聚焦翻译"是低使用率特性。综合判断,增加的复杂度无法被收益正当化,故被拒绝。
5. 当前仓库中的落地形态:segment 已从提取流程移除
对照仓库现状可以看到该决策的落地痕迹。Makefile 中extract_translations目标目前为:
extract_translations: ## extract localizable strings from sources uv run i18n_tool extract --no-segment -v cd conf/locale/en/LC_MESSAGES && msgcat djangojs.po underscore.po -o djangojs.po注意两点:
- 提取命令显式带上了
--no-segment参数——即不再执行 segment 分片步骤,提取结果直接产出未拆分的 po 文件。这与决策"只推两个文件"一致:既然不再按文件分工协作,分片就没有意义了; - 随后用
msgcat将djangojs.po与underscore.po合并,使 JS 侧字符串也归入标准的djangojs.po。
conf/locale/config.yaml中的segment段落仍保留在文件中,但当前提取主流程已绕过它(--no-segment);从源码结构看,它更多是作为历史配置与文档性质的存在,供了解分片机制的读者参考。
拉取与编译侧则完全切换到 openedx-atlas 工具链(requirements 中锁定 openedx-atlas 0.7.0),Makefile中的相关目标为:
pull_translations: clean_translations ## pull translations via atlas make pull_xblock_translations make pull_plugin_translations uv run atlas pull $(ATLAS_OPTIONS) \ translations/edx-platform/conf/locale:conf/locale \ $(ATLAS_EXTRA_SOURCES) uv run python manage.py lms compilemessages uv run python manage.py lms compilejsi18n uv run python manage.py cms compilejsi18n要点:
- 前置的 clean_translations 目标会删除
conf/locale/下除eo(测试语言)以外的全部.po/.mo,并清理 xblock/插件及 JS 编译产物,保证每次都是全新拉取; atlas pull translations/edx-platform/conf/locale:conf/locale明确体现 OEP-58 模式下"从 openedx-translations 仓库路径拉取到本仓库conf/locale"的映射关系,与决策 Context 中"通过 openedx-atlas 命令行工具拉取翻译"的描述一致;- 拉取后分别执行
compilemessages(编译 Django 的.po→.mo)与compilejsi18n(编译 JS 翻译),LMS 与 CMS 两侧都覆盖; - 另有
detect_changed_source_translations目标(i18n_tool changed)用于检查翻译源文件是否过期,适合 CI 场景使用; conf/locale/en/LC_MESSAGES目录在当前仓库中为空(源语言不保存 po 文件,提取产物生成于运行时),而 conf/locale/eo/LC_MESSAGES 中的django.po与djangojs.po各只有一个——测试语言同样只维护两个标准文件,是决策落地后的最小数据面。
6. 小结:一次"减法"决策的启示
这篇决策记录的价值不仅在于结论本身,更在于它示范了如何用完整证据链做国际化基础设施的简化决策:
- 先陈述现状与动机:拆分是为了"LMS/CMS 语言覆盖不对称",合并回 2 个文件是 Django 运行时的硬约束;
- 再给出决策与双向后果:2 文件方案把翻译资源从 11 个降到 2 个、移除切版合并步骤,代价是失去按 learner/educator 文案分层的协作粒度;
- 完整记录被否决方案及其配置细节:四文件方案连
config.extract-oep58.yaml、config.pull-oep58.yaml与 Makefile 条件分支都给出了可运行草案,最终以"复杂度不被收益正当化"否决; - 最后让仓库代码与决策互相印证:
--no-segment提取、atlas pull拉取、eo 目录下仅存django.po/djangojs.po,均与决策结果吻合。
对于维护 openedx-platform 或类似 Django + 多模板引擎(Mako/Underscore/React)国际化链路的团队,可直接参考的落点包括:i18n 工作流总配置 conf/locale/config.yaml、三类 Babel 提取配置(babel_mako.cfg、babel_third_party.cfg、babel_underscore.cfg),以及 Makefile 中extract_translations、pull_translations、detect_changed_source_translations三个目标构成的"提取—拉取—校验"闭环。
【免费下载链接】openedx-platformThe Open edX LMS & Studio, powering education sites around the world!项目地址: https://gitcode.com/GitHub_Trending/ed/openedx-platform
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考