news 2026/9/16 18:26:54

openedx-platform 翻译文件标准化决策:为什么只保留 django.po 与 djangojs.po 两个资源文件

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
openedx-platform 翻译文件标准化决策:为什么只保留 django.po 与 djangojs.po 两个资源文件

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.podjango-partial.po以及另外 9 个文件,合计 11 个资源文件。拆分的初衷是让 LMS(学习者端)可以支持比 CMS(Studio,教师端)更多的语言——新语言只需翻译 LMS 相关字符串,不必同步翻译 Studio 字符串。
  • 拆分手段是edx-i18n-tools提供的i18n_tools segment命令,目标同样是降低翻译者的认知负担。
  • 在从 Transifex 拉取翻译或切版(release cut)时,这些分片最终会合并回两个文件django.podjangojs.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.podjangojs.po及其编译产物.mo,这正是 Makefile 中清理逻辑特意保留的对象(见第 4 节)。

2.2 忽略目录与第三方提取源

配置中的ignore_dirs列出了不参与字符串提取的目录,包括*/migrations*/envsnode_modulesconfdocs、各类资源目录(*/images*/sass等)、测试目录(common/test*/tests)以及自动生成的 JS 翻译产物lms/static/js/i18ncms/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.podjangojs-studio.pomako-studio.pounderscore-studio.po,其余字符串留在原始文件中。这正是"LMS 先行支持新语言、Studio 可滞后翻译"思路的实现载体。

2.4 generate_merge:分片如何合回两个运行文件

generate_merge定义了生成步骤的合并规则,也解释了为什么 eo 测试翻译的 django.po 文件头 中会连续出现django-partial.podjango-studio.pomako.pomako-studio.powiki.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.podjangojs.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.pomako.podjango-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.po
pull_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

注意两点:

  1. 提取命令显式带上了--no-segment参数——即不再执行 segment 分片步骤,提取结果直接产出未拆分的 po 文件。这与决策"只推两个文件"一致:既然不再按文件分工协作,分片就没有意义了;
  2. 随后用msgcatdjangojs.pounderscore.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.podjangojs.po各只有一个——测试语言同样只维护两个标准文件,是决策落地后的最小数据面。

6. 小结:一次"减法"决策的启示

这篇决策记录的价值不仅在于结论本身,更在于它示范了如何用完整证据链做国际化基础设施的简化决策:

  1. 先陈述现状与动机:拆分是为了"LMS/CMS 语言覆盖不对称",合并回 2 个文件是 Django 运行时的硬约束;
  2. 再给出决策与双向后果:2 文件方案把翻译资源从 11 个降到 2 个、移除切版合并步骤,代价是失去按 learner/educator 文案分层的协作粒度;
  3. 完整记录被否决方案及其配置细节:四文件方案连config.extract-oep58.yamlconfig.pull-oep58.yaml与 Makefile 条件分支都给出了可运行草案,最终以"复杂度不被收益正当化"否决;
  4. 最后让仓库代码与决策互相印证--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_translationspull_translationsdetect_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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 18:26:54

工业自动化托盘输送机程序设计与优化实战

1. 托盘输送机程序概述在工业自动化领域,托盘输送机系统就像工厂的"血管网络",负责将原材料、半成品和成品精准输送到各个加工环节。作为这个系统的"大脑",控制程序的质量直接决定了整个生产线的运行效率。我从事自动化控…

作者头像 李华
网站建设 2026/9/16 18:26:31

Mac 磁盘空间 30 秒释放:Mole 一键系统清理与优化工具

Mac 磁盘空间 30 秒释放:Mole 一键系统清理与优化工具 【免费下载链接】Mole 🐹 Clean, uninstall, analyze, optimize, and monitor your Mac. Free open-source CLI, plus a native Mac app. 项目地址: https://gitcode.com/GitHub_Trending/mole15/…

作者头像 李华
网站建设 2026/9/16 18:26:19

C#影院售票系统源码解析:从分层架构到并发锁票实践

简介:一套基于C#语言的影院售票系统完整源码,适合C#/.NET初学者、课程设计或毕业设计参考。系统依托.NET Framework与SQL数据库,划分为前台、后台与数据库三大模块,涵盖用户注册登录、影片资讯展示、选座购票支付、个人中心&#…

作者头像 李华
网站建设 2026/9/16 18:24:37

基于GUVB-C31SM的UVB测量:从传感器选型到标定实战

做紫外线测量这件事,听起来像是实验室里才有的活儿,但实际上做消毒灯、植物补光、光固化设备、甚至户外紫外线监测的人都在碰。一个让初学者特别头疼的问题是:紫外传感器型号又多又杂,GUVB-C31SM 这类光电二极管到底怎么接才能读出…

作者头像 李华
网站建设 2026/9/16 18:23:21

Pentagi:渗透测试AI代理架构原理与实战搭建

1. “Pentagi”不是产品名,而是渗透测试AI代理架构的代号级命名实践 你搜“pentagi”,页面上几乎全是Docker、Neo4j、安装教程、报错日志——没有官网、没有GitHub仓库、没有文档首页。这不是一个已发布的SaaS工具,也不是某家初创公司的商业…

作者头像 李华