Skip to content

国际化

GPUI Component 为组件提供了内置翻译,目前包含 enzh-CNzh-HK。应用可以新增语言或覆盖个别翻译,而不需要复制完整的内置 locale 文件。

此功能需要 rust-i18n 4.2 或更高版本。

添加依赖

在持有 locale 文件的应用 crate 中添加 rust-i18n

toml
[dependencies]
gpui-component = "0.5"
rust-i18n = "4.2"

创建应用 locale 文件

在应用 crate 中创建 locales/ui.yml,并将组件翻译放在 gpui_component namespace 下:

yaml
_version: 2
gpui_component:
  Calendar:
    week.0:
      fr: Di
    month.January:
      fr: Janvier
  DatePicker:
    placeholder:
      fr: Sélectionner une date

namespace 必须是 gpui_component,它对应 Rust crate 名称 gpui-component,其中连字符转换为下划线。可在 GPUI Component 内置 locale 文件中查看可用的翻译 key。

注册扩展

首先在应用的 crate root 初始化 locales:

rust
rust_i18n::i18n!("locales", fallback = "en");

然后在初始化 GPUI Component 之前注册扩展:

rust
app.run(move |cx| {
    rust_i18n::extend!(gpui_component);
    gpui_component::init(cx);

    // 打开窗口并初始化应用的其他部分。
});

应用启动期间只需调用一次 extend!

查找优先级

应用提供的翻译优先于组件的内置翻译:

text
应用 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! 调用能访问到内置翻译:

rust
// GPUI Component 组件内部:先查应用,再查内置。
t!("Calendar.month.February")             // -> "February"

// 应用代码中:只会读取应用自己的 locale 文件。
t!("gpui_component.Calendar.month.February")   // -> 未定义时返回 key 本身

组件文案应当通过渲染组件来呈现,不要自己去查这些 key。

切换语言

gpui-component 已经再导出 locale 相关方法,应用无需直接依赖 rust-i18n 即可切换语言:

rust
gpui_component::set_locale("fr");
let current = gpui_component::locale();

组件随后会按照上述优先级,使用当前 locale 查找翻译文本。

当前 locale 属于 GPUI 不感知的全局状态,修改它本身不会触发重绘。展示翻译文本的 view 需要自行通知:

rust
gpui_component::set_locale("fr");
cx.notify();