多语言
Midway 提供了多语言组件,让业务可以快速指定不同的语言,展示不同的文案,也可以在 HTTP 场景配合请求参数,请求头等方式来使用。
相关信息:
描述 | |
---|---|
可用于标准项目 | ✅ |
可用于 Serverless | ✅ |
可用于一体化 | ✅ |
包含独立主框架 | ❌ |
包含独立日志 | ❌ |
安装组件
$ npm i @midwayjs/i18n@3 --save
或者在 package.json
中增加如下依赖后,重新安装。
{
"dependencies": {
"@midwayjs/i18n": "^3.0.0",
// ...
},
}
使用组件
将 i18n 组件配置到代码中。
import { Configuration } from '@midwayjs/core';
import * as i18n from '@midwayjs/i18n';
@Configuration({
imports: [
// ...
i18n
]
})
export class MainConfiguration {
//...
}
使用
组件提供了 MidwayI18nService
服务,用于翻译多语言文本。
使用 translate
方法,传入不同的文本关键字和参数,返回不同语言的文本内容。
@Controller('/')
export class UserController {
@Inject()
i18nService: MidwayI18nService;
@Get('/')
async index(@Query('username') username: string) {
return this.i18nService.translate('HELLO_MESSAGE', {
args: {
username
},
});
}
}
配置多语言文案
你可以在配置文件中直接配置,但是大多数情况下,文案会很多,有时候甚至可能文案在远端服务上,这个时候直接配置就不太现实。
一般来说,我们会将文案单独放到某个文案配置目录中,比如 src/locales
。
以 src/locale
这个目录为例,我们举个例子,结构如下:
.
├── src
│ ├── locales
| │ ├── en_US.json
| │ └── zh_CN.json
│ └── controller
│ └── home.controller.ts
├── package.json
└── tsconfig.json
这里我们建了两个多语言的文件,en_US.json
和 zh_CN.json
,分别代表英文和中文。
文件内容分别如下:
// src/locales/en_US.json
{
"hello": "Hello {username}",
"email": "email id",
"login": "login account",
"createdAt": "register date"
}
// src/locales/zh_CN.json
{
"hello": "你好 {username}",
"email": "邮箱",
"login": "帐号",
"createdAt": "注册时间"
}
每行一个字符串对,是一个标准的 JSON 格式内容,也可以使用 js/ts 文件,花括号中是可替换的参数占位。
同时,需要在配置中加入这两个 JSON,其中 default
是语言的默认分组。
// src/config/config.default.ts
export default {
// ...
i18n: {
// 把你的翻译文本放到这里
localeTable: {
en_US: {
default: require('../locale/en_US'),
},
zh_CN: {
default: require('../locale/zh_CN'),
}
},
}
}
这样就可以使用了,使用输出如下。
this.i18nService.translate('hello', {
args: {
username: 'harry',
},
locale: 'en_US',
});
// output: Hello harry.
this.i18nService.translate('hello', {
args: {
username: 'harry',
},
locale: 'zh_CN',
});
// output: 你好 harry.
多语言文案分组
在如下配置中,用户配置的多语言文案在 default
分组中。
// src/config/config.default.ts
export default {
// ...
i18n: {
// 把你的翻译文本放到这里
localeTable: {
en_US: {
default: require('../locale/en_US'),
},
zh_CN: {
default: require('../locale/zh_CN'),
}
},
}
}
这样做的好处是,在其他组件或者业务代码中,我们也可以使用不同的分组名,来添加其他的多语言文案。
比如:
// src/config/config.default.ts
export default {
// ...
i18n: {
// 把你的翻译文本放到这里
localeTable: {
en_US: {
default: require('../locale/en_US'),
user: require('../locale/user_en_US'),
},
zh_CN: {
default: require('../locale/zh_CN'),
user: require('../locale/user_zh_CN'),
}
},
}
}
在代码中,如果调用非默认分组,需要指定分组参数。
this.i18nService.translate('user.hello', {
args: {
username: 'harry',
},
group: 'user', // 指定其他分组
locale: 'en_US',
});
多语言文案格式
多语言文本中可以添加参数,参数可以有 对象
和 数组
两种形式。
对象形式如下,使用花括号作为占位符。
Hello {username}
使用时,通过配置传递,按对象 key 覆盖变量。
async index(@Query('username') username: string) {
return this.i18nService.translate('hello', {
args: {
username
},
});
}
数组形式如下,使用数字作为占位符。
Hello {0}
使用时,通过配置传递,格式是数组形式,按数组顺序覆盖数字变量。
async index(@Query('username') username: string) {
return this.i18nService.translate('hello', {
args: [username]
});
}
动态添加多语言文案
有时候,多语言文案可能放在远端,比如数据库等,我们可以通过 addLocale
方法进行动态添加。
比如,在配置加载后,代码使用前。
// configuration.ts
// ...
@Configuration({
imports: [
koa,
i18n
]
})
export class MainConfiguration {
@Inject()
i18nService: MidwayI18nService;
async onReady() {
this.i18nService.addLocale('zh_TW', {
hello: '你好,{username} 美麗的世界'
});
}
// ...
}
在代码中就可以使用。
async index(@Query('username') username: string) {
return this.i18nService.translate('hello', {
args: [username],
locale: 'zh_TW'
});
}
通过参数指定当前语言
一般情况下,默认语言为 en_US
,用户的浏览器访问一般会自带 Accept-Language
头,所以会正确识别语言。比如用中文浏览器访问,就能正常显示中文。
除此之外,在 HTTP 场景下可以通过 URL Query,Cookie,Header 来指定语言。
优先级从上到下:
- query: /?locale=en-US
- cookie: locale=zh-TW
- header: Accept-Language: zh-CN,zh;q=0.5
当传递了这些参数之后,多语言数据会自动保存到当前用户的 Cookie 中,下次请求会直接用该设定好的语言。
手动设置语言
可以通过调用 saveRequestLocale
设置当前语言。
async index() {
// ...
this.i18nService.saveRequestLocale('zh_CN');
}
如果开启了 writeCookie
配置,设置后会保存到当前用户的 Cookie 中,下次请求会使用该设置。