2022-11-06 06:15:00 +00:00
# Internationalization
2022-10-31 14:41:24 +00:00
2022-11-06 06:15:00 +00:00
Internationalization in NocoBase is implemented based on [i18next ](https://npmjs.com/package/i18next ).
2022-10-31 14:41:24 +00:00
2022-11-06 06:15:00 +00:00
## How to register a multilingual package?
2022-10-31 14:41:24 +00:00
```ts
export class MyPlugin extends Plugin {
load() {
this.app.i18n.addResources('zh-CN', 'test', {
Hello: '你好',
World: '世界',
});
this.app.i18n.addResources('en-US', 'test', {
Hello: 'Hello',
World: 'World',
});
}
}
```
2022-11-06 06:15:00 +00:00
## Two i18n instances
2022-10-31 14:41:24 +00:00
### app.i18n
2022-11-06 06:15:00 +00:00
Global i18n instance, typically used in the CLI.
2022-10-31 14:41:24 +00:00
```ts
2022-11-06 06:15:00 +00:00
app.i18n.t('World') // "世界" or "World"
2022-10-31 14:41:24 +00:00
```
### ctx.i18n
2022-11-06 06:15:00 +00:00
CloneInstance of global i18n with a completely independent context for each request, typically used to respond to multilingual messages based on the client language.
2022-10-31 14:41:24 +00:00
```ts
app.use(async (ctx, next) => {
ctx.body = `${ctx.i18n.t('Hello')} ${ctx.i18n.t('World')}` ;
await next();
});
```
2022-11-06 06:15:00 +00:00
The client request parameters can be placed in the query string
2022-10-31 14:41:24 +00:00
```bash
GET /?locale=en-US HTTP/1.1
Host: localhost:13000
```
2022-11-06 06:15:00 +00:00
or in the request headers
2022-10-31 14:41:24 +00:00
```bash
GET / HTTP/1.1
Host: localhost:13000
X-Locale: en-US
```
2022-11-06 06:15:00 +00:00
## Suggested configuration
2022-10-31 14:41:24 +00:00
2022-11-06 06:15:00 +00:00
With English text as the key and translation as the value, this has the advantage that even if multiple languages are missing, it will be displayed in English and will not cause reading barriers, e.g.
2022-10-31 14:41:24 +00:00
```ts
i18n.addResources('zh-CN', 'your-namespace', {
'Show dialog': '显示对话框',
'Hide dialog': '隐藏对话框'
});
```
2022-11-06 06:15:00 +00:00
To make it easier to manage multilingual files, it is recommended to create a `locale` folder in the plugin and place all the corresponding language files in it:
2022-10-31 14:41:24 +00:00
```bash
|- /my-plugin
|- /src
|- /server
2022-11-06 06:15:00 +00:00
|- locale # Multi-language folder
|- en-cn.ts
2022-10-31 14:41:24 +00:00
|- en-US.ts
```
2022-11-06 06:15:00 +00:00
## Example
2022-10-31 14:41:24 +00:00
2022-11-06 06:15:00 +00:00
### Server-side error alert
2022-10-31 14:41:24 +00:00
2022-11-06 06:15:00 +00:00
For example, when a user places an order for a product in the store, if the product is not in stock, or not on the shelf, then the order interface should return the appropriate error when it is called.
2022-10-31 14:41:24 +00:00
```ts
const namespace = 'shop';
export default class ShopPlugin extends Plugin {
async load() {
this.app.i18n.addResources('zh-CN', namespace, {
'No such product': '商品不存在',
'Product not on sale': '商品已下架',
'Out of stock': '库存不足',
});
this.app.resource({
name: 'orders',
actions: {
async create(ctx, next) {
const productRepo = ctx.db.getRepository('products');
const product = await productRepo.findOne({
filterByTk: ctx.action.params.values.productId
2022-11-06 06:15:00 +00:00
productId });
2022-10-31 14:41:24 +00:00
if (!product) {
return ctx.throw(404, ctx.t('No such product'));
}
if (!product.enabled) {
return ctx.throw(400, ctx.t('Product not on sale'));
}
if (!product.inventory) {
return ctx.throw(400, ctx.t('Out of stock'));
}
const orderRepo = ctx.db.getRepository('orders');
ctx.body = await orderRepo.create({
values: {
productId: product.id,
quantity: 1,
totalPrice: product.price,
userId: ctx.state.currentUser.id
}
});
next();
}
}
});
}
}
```