tachybase_todo/docs/zh-CN/development/client/i18n.md

141 lines
3.5 KiB
Markdown
Raw Normal View History

# 国际化
客户端的国际化多语言基于 npm 包 [react-i18next](https://npmjs.com/package/react-i18next) 实现,在应用顶层提供了 `<I18nextProvider>` 组件的包装,可以在任意位置直接使用相关的方法。
添加语言包:
```tsx | pure
import { i18n } from '@nocobase/client';
i18n.addResources('zh-CN', 'test', {
Hello: '你好',
World: '世界',
});
```
2022-11-08 14:13:44 +08:00
注:这里第二个参数填写的 `'test'` 是语言的命名空间通常插件自己定义的语言资源都应该按自己插件包名创建特定的命名空间以避免和其他语言资源冲突。NocoBase 中默认的命名空间是 `'client'`,大部分常用和基础的语言翻译都放置在此命名空间。当没有提供所需语言时,可在插件自身的命名空间内进行扩展定义。
在组件中调用翻译函数:
```tsx | pure
import React from 'react';
import { useTranslation } from 'react-i18next';
export default function MyComponent() {
// 使用之前定义的命名空间
const { t } = useTranslation('test');
return (
<div>
<p>{t('World')}</p>
</div>
);
}
```
在 SchemaComponent 组件中可以直接使用模板方法 `'{{t(<languageKey>)}}'`,模板中的翻译函数会自动被执行:
```tsx | pure
import React from 'react';
import { SchemaComponent } from '@nocobase/client';
export default function MySchemaComponent() {
return (
<SchemaComponent
schema={{
type: 'string',
'x-component': 'Input',
'x-component-props': {
value: '{{t("Hello", { ns: "test" })}}'
},
}}
/>
);
}
```
在某些特殊情况下也需要以模板的方式定义多语言时,可以使用 NocoBase 内置的 `compile()` 方法编译为多语言结果:
```tsx | pure
import React from 'react';
import { useCompile } from '@nocobase/client';
const title = '{{t("Hello", { ns: "test" })}}';
export default function MyComponent() {
const { compile } = useCompile();
return (
<div>{compile(title)}</div>
);
}
```
## 建议配置
以英文文案为 key翻译为 value这样的好处即使多语言缺失也会以英文显示不会造成阅读障碍
```ts
i18n.addResources('zh-CN', 'my-plugin', {
'Show dialog': '显示对话框',
'Hide dialog': '隐藏对话框'
});
```
为了更方便管理多语言文件,推荐在插件中创建一个 `locale` 文件夹,并把对应语言文件都放置在其中方便管理:
```bash
|- /my-plugin
|- /src
|- /client
|- locale # 多语言文件夹
|- zh-CN.ts
|- en-US.ts
```
## 示例
### 客户端组件多语言
例如订单状态的组件,根据不同值有不同的文本显示:
```tsx | pure
import React from 'react';
import { Select } from 'antd';
import { i18n } from '@nocobase/client';
import { useTranslation } from 'react-i18next';
i18n.addResources('zh-CN', 'sample-shop-i18n', {
Pending: '已下单',
Paid: '已支付',
Delivered: '已发货',
Received: '已签收'
});
const ORDER_STATUS_LIST = [
{ value: -1, label: 'Canceled (untranslated)' },
{ value: 0, label: 'Pending' },
{ value: 1, label: 'Paid' },
{ value: 2, label: 'Delivered' },
{ value: 3, label: 'Received' },
]
function OrderStatusSelect() {
const { t } = useTranslation('sample-shop-i18n');
return (
<Select style={{ minWidth: '8em' }}>
{ORDER_STATUS_LIST.map(item => (
<Select.Option value={item.value}>{t(item.label)}</Select.Option>
))}
</Select>
);
}
export default function () {
return (
<OrderStatusSelect />
);
}
```