VonaJS I18n如何让Swagger支持多种语言?

摘要:VonaJS提供的I18n支持模块化体系。每个业务模块都可以单独提供自己的 I18n 语言资源。我们先了解I18n的一般用法,然后再看看如何支持Swagger多语言
VonaJS提供的I18n支持模块化体系。每个业务模块都可以单独提供自己的 I18n 语言资源。我们先了解I18n的一般用法,然后再看看如何支持Swagger多语言 初始化代码骨架 我们先在模块demo-student中初始化I18n的代码骨架 1. Cli命令 $ vona :init:locale demo-student 2. 菜单命令 右键菜单 - [模块路径]: `Vona Init/Locale` 定义语言资源 以模块demo-student为例,定义模块的语言资源: 英文 src/module/demo-student/src/config/locale/en-us.ts export default { + StudentName: 'Student Name', }; 中文 src/module/demo-student/src/config/locale/zh-cn.ts export default { + StudentName: '学生名称', }; 使用语言资源 可以通过 Scope 实例提供的locale对象获取模块的语言资源,支持类型化提示 class ControllerStudent { @Web.get('test') test() { // use current locale const message1 = this.scope.locale.StudentName(); // use locale en-us const message2 = this.scope.locale.StudentName.locale('en-us'); // use locale zh-cn const message3 = this.scope.locale.StudentName.locale('zh-cn'); console.log(message1, message2, message3); } } 跨模块使用语言资源 class ControllerStudent { @Web.get('test') test() { // use current locale const message1 = this.$scope.demoStudent.locale.StudentName(); // use locale en-us const message2 = this.$scope.demoStudent.locale.StudentName.locale('en-us'); // use locale zh-cn const message3 = this.$scope.demoStudent.locale.StudentName.locale('zh-cn'); console.log(message1, message2, message3); } } 覆盖语言资源 可以使用项目级别的语言资源覆盖模块级别的语言资源 英文 src/backend/config/locale/en-us.ts export default { modules: { + 'demo-student': { + StudentName: 'Student Name!', + }, }, }; 中文 src/backend/config/locale/zh-cn.ts export default { modules: { + 'demo-student': { + StudentName: '学生名称!', + }, }, }; 当前locale 1. 获取当前locale const locale = this.ctx.locale; 2. 设置当前locale this.ctx.locale = 'en-us'; 3. 获取缺省locale const localeDefault = this.$scope.i18n.config.defaultLocale; 获取当前locale的规则 当用户访问后端 API 时,后端会自动根据规则获取当前 locale 1. 模块配置 I18n 是由模块 a-i18n 提供的核心能力,可以在 App config 中修改模块的配置: src/backend/config/config/config.ts // modules config.modules = { 'a-i18n': { defaultLocale: 'en-us', queryField: 'x-vona-locale', headerField: 'x-vona-locale', cookieField: 'locale', }, }; 名称 说明 defaultLocale Default locale queryField 从request query中获取当前locale,query key默认为x-vona-locale headerField 从request header中获取当前locale,header key默认为x-vona-locale cookieField 从request cookie中获取当前locale,cookie key默认为locale 2. 规则次序 系统按以下次序,依次判断当前 locale queryField > headerField > cookieField > Header: Accept-Language > defaultLocale 添加新语言 VonaJS 默认提供了两个语言:en-us和zh-cn。下面演示如何添加新语言zh-tw 1. 添加类型定义 采用接口合并机制添加新语言的类型定义 在 VSCode 编辑器中,输入代码片段recordlocale,自动生成代码骨架: declare module 'vona' { export interface ILocaleRecord { : never; } } 调整代码,然后添加zh-tw declare module 'vona' { export interface ILocaleRecord { + 'zh-tw': never; } } 2. 添加语言资源 新建语言文件zh-tw.ts,然后添加语言资源 src/module/demo-student/src/config/locale/zh-tw.ts export default { StudentName: '學生名稱', }; 复数 1. 定义语言资源 src/module/demo-student/src/config/locale/en-us.ts export default { + TestApples_: '%d apples', + TestApples_0: 'no apples', + TestApples_1: 'one apple', }; src/module/demo-student/src/config/locale/zh-cn.ts export default { + TestApples_: '%d个苹果', + TestApples_0: '没有苹果', }; 2. 使用语言资源 this.ctx.locale = 'en-us'; const apple0 = this.scope.locale.TestApples_(0); const apple1 = this.scope.locale.TestApples_(1); const apple2 = this.scope.locale.TestApples_(2); console.log(`${apple0}, ${apple1}, ${apple2}`); 控制台输出如下: no apples, one apple, 2 apples TestApples_: 缺省语言资源。语言资源添加后缀_,可以提示开发者该语言资源需要传入参数 TestApples_{n}: 可以针对任何具体的n提供独立的语言资源。系统在进行语言翻译时,如果找不到具体n的语言资源,就使用缺省语言资源TestApples_ 复数: 多参数 如果语言资源支持多参数,那么可以明确指定哪个参数支持复数 1. 定义语言资源 src/module/demo-student/src/config/locale/en-us.ts export default { + TestNameApples_: '%s has %d apples', + TestNameApples_0_1: '%s has no apples', + TestNameApples_1_1: '%s has one apple', }; src/module/demo-student/src/config/locale/zh-cn.ts export default { + TestNameApples_: '%s有%d个苹果', + TestNameApples_0_1: '%s没有苹果', }; 2. 使用语言资源 this.ctx.locale = 'en-us'; const apple0 = this.scope.locale.TestNameApples_('Tom', 0); const apple1 = this.scope.locale.TestNameApples_('Tom', 1); const apple2 = this.scope.locale.TestNameApples_('Tom', 2); console.log(`${apple0}, ${apple1}, ${apple2}`); 控制台输出如下: Tom has no apples, Tom has one apple, Tom has 2 apples TestNameApples_: 缺省语言资源。语言资源添加后缀_,可以提示开发者该语言资源需要传入参数 TestNameApples_{n}_{ordinal}: ordinal代表参数序数 Swagger/Openapi VonaJS 提供了一组工具函数,为 Swagger/Openapi 实现 I18n 国际化 比如,为EntityStudent的字段name提供国际化的title信息 1. $localeScope 在设置字段 title 信息时,要使用语言资源FullKey。在实际生成 Swagger/Openapi 元数据时,系统会自动将语言资源FullKey翻译为指定的语言 + import { $localeScope } from 'vona'; class EntityStudent { + @Api.field(v.title($localeScope('demo-student', 'Name'))) name: string; } v.title: 设置 title 信息 $localeScope: 传入模块名称和语言资源Key,从而生成语言资源FullKey: demo-student::Name 2. $locale VonaJS 还提供了一个简化的工具函数$locale + import { $locale } from '../.metadata/index.ts'; class EntityStudent { + @Api.field(v.title($locale('Name'))) name: string; } $locale: 传入语言资源Key,从而生成语言资源FullKey: demo-student::Name 每个模块都提供了$locale 函数,因此,使用本模块的$locale 函数就可以取得模块名称 资源 Github:https://github.com/vonajs/vona 文档:https://vona.js.org