国际化
GPUI Component 为组件提供了内置翻译,目前包含 en、zh-CN、zh-HK。应用可以新增语言或覆盖个别翻译,而不需要复制完整的内置 locale 文件。
此功能需要 rust-i18n 4.2 或更高版本。
添加依赖
在持有 locale 文件的应用 crate 中添加 rust-i18n:
[dependencies]
gpui-component = "0.5"
rust-i18n = "4.2"创建应用 locale 文件
在应用 crate 中创建 locales/ui.yml,并将组件翻译放在 gpui_component namespace 下:
_version: 2
gpui_component:
Calendar:
week.0:
fr: Di
month.January:
fr: Janvier
DatePicker:
placeholder:
fr: Sélectionner une datenamespace 必须是 gpui_component,它对应 Rust crate 名称 gpui-component,其中连字符转换为下划线。可在 GPUI Component 内置 locale 文件中查看可用的翻译 key。
注册扩展
首先在应用的 crate root 初始化 locales:
rust_i18n::i18n!("locales", fallback = "en");然后在初始化 GPUI Component 之前注册扩展:
app.run(move |cx| {
rust_i18n::extend!(gpui_component);
gpui_component::init(cx);
// 打开窗口并初始化应用的其他部分。
});应用启动期间只需调用一次 extend!。
查找优先级
应用提供的翻译优先于组件的内置翻译:
应用 locales(locales/ui.yml)
│
│ 未找到 key
▼
GPUI Component 内置 locales这种 deep merge 行为意味着:
- 新语言(例如
fr)只需提供应用需要的 key。 - locale 和 key 都相同时,应用提供的翻译会覆盖内置值。
- 应用未提供的 key 会继续使用组件内置值。
- GPUI Component 后续新增的翻译无需复制,也会自动可用。
例如,只定义 gpui_component.Calendar.month.January.en 会修改一月份的英文标签,其他英文日历标签仍然来自 GPUI Component。
命名空间只对组件内部的查找生效
extend! 改变的是 GPUI Component 查找自身 key 的方式,它不会让应用自己的 t! 调用能访问到内置翻译:
// GPUI Component 组件内部:先查应用,再查内置。
t!("Calendar.month.February") // -> "February"
// 应用代码中:只会读取应用自己的 locale 文件。
t!("gpui_component.Calendar.month.February") // -> 未定义时返回 key 本身组件文案应当通过渲染组件来呈现,不要自己去查这些 key。
切换语言
gpui-component 已经再导出 locale 相关方法,应用无需直接依赖 rust-i18n 即可切换语言:
gpui_component::set_locale("fr");
let current = gpui_component::locale();组件随后会按照上述优先级,使用当前 locale 查找翻译文本。
当前 locale 属于 GPUI 不感知的全局状态,修改它本身不会触发重绘。展示翻译文本的 view 需要自行通知:
gpui_component::set_locale("fr");
cx.notify();