跳转至

本地化

Echo-Live 使用的是自研本地化库,位于 res/class/Translator.js,封装为 Translator 类,其本地化语法格式采用了一种较为常用的格式。

要使用本地化库,首先应当将 Translator 实例化,Echo-Live 已经做好了这一工作,实例化后的名称为 translator,并将获取本地化文本的方法绑定到了 $t 方法上。

本地化运行流程

graph TD
    A(输入键名和变量) --> B[选用设定语言];
    B --> C[根据键名查找文本];
    C --> D{是否有结果};
    D -->|是| E[根据输入变量为本地化文本赋值];
    D -->|否| F{是主语言};
    F -->|是| H(输出键名);
    F -->|否| G[选用主语言];
    G -->|Plan B| C;
    E --> I[根据 n 变量选择单复数形式];
    I --> K(输出本地化文本);

本地化函数

本地化函数是指 Translator.output() 方法,可用 $t() 代替。该方法接受以下参数:

参数名 预期类型 默认值 描述
key String 本地化键名。
variable Object {} 传入的变量。
__inPlanB Boolean false 内部参数,用于判断是否处于 Plan B。

该方法有三种预期结果:

  • 一切正常,输出本地化文本。
  • 不是主语言,未找到本地化文本,在主语言中找到了本地化文本,输出主语言的本地化文本。
  • 无论是主语言还是设定语言都没有找到本地化文本,输出键名。

该方法有两种异常表现:

  • 输出的本地化文本中变量占位符未被替换,原因是未传递相关变量,且无默认值可用。
  • 直接报错。正常使用不会出现这种情况,请检查代码或本地化数据。

用法示例

const lang = {
    // ... 这里省略了一些数据
    foo: {
        bar_1: "Hello, World!",
        bar_2: "Hello, {user}!",
        bar_3: "I have {n} apple. | I have {n} apples.",
        bar_4: "I don't have any pomelos. | I have {n} pomelo. | I have {n} pomelos."
    }
}
// 在这之后还需要将上面的数据通过 Translator.load() 方法导入
$t('foo.bar_1');
// 输出:Hello, World!

$t('foo.bar_2', { user: 'Echo' });
// 输出:Hello, Echo!

$t('foo.bar_3', { n: 1 });
// 输出:I have 1 apple. 

$t('foo.bar_3', { n: 2 });
// 输出:I have 2 apples. 

$t('foo.bar_4', { n: 0 });
// 输出:I don't have any pomelos.

$t('foo.bar_4', { n: 1 });
// 输出:I have 1 pomelo.

$t('foo.bar_4', { n: 2 });
// 输出:I have 2 pomelos.

本地化文本语法

一般情况下,您可以在本地化文本中输入任何内容,但请注意管道符 | 具有特殊含义,请避免使用,或以 | 代替。

变量

您可以为本地化文本分配一些变量,变量以花括号 {} 包括来声明。例如,要在文本中插入 name 变量,应该插入 {name}

以下是实际应用示例:

const lang = {
    // ... 这里省略了一些数据
    example_1: "Hello, {user}!",
    example_2: "Never gonna {var1}, never gonna {var2}. Never gonna {var3} and {var4} you."
}

本地化变量

除了常规的变量外,您还可以使用本地化变量。和常规变量不同的是,需要在变量名之前添加 @ 符号,而后是一个本地化键名。

以下是实际应用示例:

const lang = {
    // ... 这里省略了一些数据
    example_1: "apple",
    example_2: "Hello, {@example_1}!"
}

单复数变体

变量 n 具有特殊含义,用于处理单复数变体。使用本地化函数传入变量 n 即可进行单复数变体判断,变量 n 默认为 0。

要区分单复数文本,需要在本地化文本中插入管道符 | 分割文本,分割后的文本会自动去除左右多余空格。

如果分割了两串文本,则第一串文本会在 n 小于等于 1 时使用,第二串文本会在 n 大于等于 2 时使用。

如果分割了三串或更多串文本,则第一串文本会在 n 小于等于 0 时使用,第二串文本会在 n 等于 1 时使用,第三串文本会在 n 大于等于 2 时使用,后续的文本不会被使用。

无论变量 n 是否被调用,只要有管道符 | 存在都可用进行单复数变体判断。

示例如下:

这里是单数形式 | 这里是复数形式
这里小于等于 0 | 这里是 1 | 这里大于等于 2
0 | 1 | 2 | 这里不会被使用 | 这里也不会 | ...

以下是实际应用示例:

const lang = {
    // ... 这里省略了一些数据
    example_1: "I have {n} apple. | I have {n} apples.",
    example_2: "I don't have any pomelos. | I have {n} pomelo. | I have {n} pomelos."
}