国际化
使用场景
为了方便开发多语言应用,框架内置了国际化(I18n
)支持,由 egg-i18n 插件提供。
i18n
是internationalization
的缩写,代表i
和n
之间有 18 个字母。
- 开发者需定义多个
locale
多语言文件。 - 开发者在
Controller
或View
中使用对应的语法糖渲染字符串。 - 插件会根据约定,渲染指定的多语言字符串。
locale
定义 目录规范
多种语言的配置是独立的,统一存放在 config/locale/*.js
下。
showcase
└── config
├── plugin.js
├── config.default.js
└── locale
├── en-US.js
└── zh-CN.js
不仅对于应用目录生效,在框架,插件的 config/locale
目录下同样生效。
友情提示
注意单词拼写,是 locale 不是 locals。
文件格式
支持 js
和 JSON
两种格式:
// config/locale/zh-CN.js
module.exports = {
Email: '邮箱',
};
或
// config/locale/zh-CN.json
{
"Email": "邮箱"
}
占位符
支持类似 util.format()
的 %s
,%j
等占位符语法。
// config/locale/zh-CN.js
module.exports = {
'Welcome back, %s!': '欢迎回来,%s!',
};
ctx.__('Welcome back, %s!', 'Shawn');
// zh-CN => 欢迎回来,Shawn!
// en-US => Welcome back, Shawn!
同时支持数组下标占位符方式,例如:
// config/locale/zh-CN.js
module.exports = {
'Hello {0}! My name is {1}.': '你好 {0}! 我的名字叫 {1}。',
};
ctx.__('Hello {0}! My name is {1}.', [ 'foo', 'bar' ]);
// zh-CN => 你好 foo!我的名字叫 bar。
// en-US => Hello foo! My name is bar.
i18n
使用 ctx.__(key, ...values)
插件提供了 ctx.__(key, ...values)
来获取语言配置。
它等价于 ctx.gettext(key, ...values)
。
class HomeController extends Controller {
async index() {
const ctx = this.ctx;
ctx.body = {
// zh-CN => 邮箱
// en-US => Email
email: ctx.__('Email'),
// zh-CN => 欢迎回来,Shawn!
// en-US => Welcome back, Shawn!
message: ctx.__('Welcome back, %s!', 'Shawn'),
// zh-CN => 你好 foo!我的名字叫 bar。
// en-US => Hello foo! My name is bar.
descriptions: ctx.__('Hello {0}! My name is {1}.', [ 'foo', 'bar' ]),
};
}
}
在 View 中使用
插件也同时把对应的语法糖注入到 ctx.locals
上,因此也可以直接在模板引擎里面使用:
<li>{{ __('Email') }}: {{ user.email }}</li>
<li>
{{ __('Welcome back, %s!', user.name) }}
</li>
<li>
{{ __('Hello {0}! My name is {1}.', ['foo', 'bar']) }}
</li>
切换语言
默认语言
默认语言是 en-US
。假设我们想修改默认语言为简体中文:
// config/config.default.js
exports.i18n = {
defaultLocale: 'zh-CN',
};
切换语言
插件也会根据请求参数不同,自动选择指定的语言。
修改后会记录到 locale
这个 Cookie
,下次请求直接用设定好的语言。
优先级从高到低:
Query
:/?locale=en-US
Cookie
:locale=zh-TW
Header
:Accept-Language: zh-CN,zh;q=0.5
如果想修改 Query
或者 Cookie
参数名称:
// config/config.default.js
exports.i18n = {
queryField: 'locale',
cookieField: 'locale',
// Cookie 默认一年后过期, 如果设置为 Number,则单位为 ms
cookieMaxAge: '1y',
};
局限性
一般来说,国际化是需要有配套的运营后台的,该插件只是一个简化的实现,开发者根据具体情况选择使用。