- Status:
connected - Done: 普通 source-string translation catalog、模块级注册、
gettext/translate使用入口和 Babel-compatible.po导出命令已接入。 - Next: none
普通多语言用于邮件、通知、后台展示、审计展示等服务端文案。它和 API 错误响应分开:
- API 错误响应使用稳定错误码,见 Error Responses。
- 普通多语言使用英文 source string 作为默认文案和翻译 key。
只有当模块需要邮件、通知、导出说明等普通服务端文案时,才创建 translations.py 定义多语言文本:
from core.messages import ModuleTranslationCatalog, define_module_translation_catalogs
TRANSLATION_CATALOGS = define_module_translation_catalogs(
"orders",
catalogs=[
ModuleTranslationCatalog(
locale="zh-CN",
messages={
"Order created": "订单已创建",
"Order {order_id} created": "订单 {order_id} 已创建",
},
)
],
)默认 domain 等于 app label。需要拆分 domain 时可以显式传:
ModuleTranslationCatalog(
locale="zh-CN",
domain="orders_email",
messages={"Your order has shipped": "你的订单已发货"},
)from .translations import TRANSLATION_CATALOGS
from core.apps import AppModule
module = AppModule(
label="orders",
version="0.1.0",
translation_catalogs=TRANSLATION_CATALOGS,
)translations.py 不是每个模块的默认必需文件。check_app() 会校验 TranslationCatalog.owner_module 必须等于 app label,并拒绝同一 locale/domain 下重复 source string。
业务代码可以用 translate():
from core.messages import translate
title = translate(
"Order {order_id} created",
domain="orders",
params={"order_id": "ord_1"},
)也可以用 gettext 风格别名:
from core.messages import gettext as _
title = _("Order created", domain="orders")找不到翻译时会返回 source string,所以英文 source string 是默认文案。
翻译文本使用 Python format 风格占位:
_("Order {order_id} created", domain="orders", params={"order_id": "ord_1"})占位参数必须显式传入 params。不要把完整业务对象或敏感字段传给翻译层。
每个模块用 Python 定义 catalog,统一命令导出 Babel/gettext 兼容 .po 文件:
core i18n export-babel --installed-app apps.orders.module --output-dir locales --json输出结构:
locales/
zh-CN/
LC_MESSAGES/
orders.po
.po 示例:
msgid ""
msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Language: zh-CN\n"
#. owner_module: orders
msgid "Order created"
msgstr "订单已创建"这让模块内的 Python 定义成为源,翻译团队可以继续使用 Babel/gettext 工具链处理 .po 文件。
- 后端普通文案可以用英文 source string 做 key。
- API 错误响应不能用英文 source string 做 key,必须用稳定错误码。
- 前端 UI 文案由前端 i18n 体系管理;后端只管理服务端产生的文案。