使用消息包
Dojo 的消息包概念是一个键值对的文本消息映射,每个键的消息内容在一种或多种语言中都有表示。
Dojo 应用程序在需要向最终用户显示消息时,通过其键引用特定消息。这避免了在代码中硬编码单一语言的文本,而是提供了一组外部化的消息,这些消息可以用一种或多种语言维护,并且可以独立于应用程序的代码进行维护。
在渲染时,Dojo 的 i18n 框架会根据引用消息键的小部件中的当前区域设置,将消息键替换为特定语言的文本内容。
Dojo 应用程序可以选择在整个应用程序中使用单个消息包,或者可以将消息分解为更细粒度,并更紧密地与它们引用的一个小部件(或多个小部件)进行范围划分,最终导致应用程序包含多个消息包。
包默认语言
每个消息包都有自己的一组支持的语言翻译。该组中的一种语言需要充当包的其余部分的默认模块。默认语言模块充当包的主要导入/引用,并满足两个主要要求
- 提供一组完整的消息键及其内容(以默认语言表示),如果包中的其他语言没有为给定键提供覆盖,则用作回退
- 列出包的其他支持语言,以及加载每个支持语言模块中的消息集的机制
TypeScript 结构
包中的每种语言都是一个 TypeScript 模块,并且需要导出一个默认对象,该对象表示消息键与其在特定语言中的翻译值的映射。
例如,包中的法语语言模块
nls/fr/main.ts
export default {
hello: 'Bonjour',
goodbye: 'Au revoir'
};
默认语言模块
指定为包默认值的语言模块的格式略有不同,与其他语言不同。默认模块需要导出一个具有以下属性的对象
messages
- 默认语言中消息键到值的映射,结构与包中其他语言导出的对象相同。这表示包支持的规范消息键集。当应用程序区域设置设置为默认值时,这些
messages
用作解析消息键时的常规查找。当使用非默认区域设置时,这些messages
用作包中其他语言模块中未包含的任何键的回退。
- 默认语言中消息键到值的映射,结构与包中其他语言导出的对象相同。这表示包支持的规范消息键集。当应用程序区域设置设置为默认值时,这些
locales
- 一个可选属性,表示区域设置标识符到函数的映射,这些函数可以加载包支持的每种语言/区域设置的消息集。
例如,一个以英语为默认语言,还支持法语、阿拉伯语和日语的包
nls/main.ts
export default {
locales: {
fr: () => import('./fr/main'),
ar: () => import('./ar/main'),
ja: () => import('./ja/main')
},
messages: {
hello: 'Hello',
goodbye: 'Goodbye'
}
};
.dojorc
{
"build-app": {
"locale": "en",
"supportedLocales": [ "fr", "ar", "ja" ]
}
}
导入和使用包
包的默认语言模块就像任何其他 TypeScript 模块一样被 import
到每个需要使用包中包含的消息集的小部件中。
例如,给定一个默认包
nls/en/MyI18nWidget.ts
export default {
messages: {
hello: 'Hello',
welcome: 'Welcome to your application'
}
};
这可以在一个小部件中导入和引用,例如
widgets/MyI18nWidget.tsx
import { create, tsx } from '@dojo/framework/core/vdom';
import i18n from '@dojo/framework/core/middleware/i18n';
import myWidgetMessageBundle from '../nls/en/MyI18nWidget';
const factory = create({ i18n });
export default factory(function MyI18nWidget({ middleware: { i18n } }) {
const { messages } = i18n.localize(myWidgetMessageBundle);
return <div title={messages.hello}>{messages.welcome}</div>;
});
由于此示例小部件通过 i18n
中间件的 .localize
方法加载其消息,因此它将继续工作,因为新的语言翻译将被添加到包的 nls/en/MyI18nWidget.ts
默认语言模块中并被引用。如果为用户当前配置的语言提供了消息集,用户将看到来自 MyI18nWidget
实例的本地化消息。
想要覆盖用户默认语言并允许在应用程序本身中更改区域设置的应用程序需要额外的设置,这将在 国际化 Dojo 应用程序 中介绍。
延迟加载与静态加载
最好在默认语言的 locales
映射中使用函数来加载其他语言翻译模块,因为这允许按需加载区域设置消息包。
但是,某些应用程序可能更喜欢将某些语言与包的默认语言模块一起静态加载,并且可以通过直接返回兼容的对象结构来实现。
包中两种加载类型的示例
import fr from './fr/main';
export default {
locales: {
// Locale providers can load translations lazily...
ar: () => import('./ar/main'),
'ar-JO': () => import('./ar-JO/main'),
// ... or return references directly.
fr
},
// Default/fallback messages
messages: {
hello: 'Hello',
goodbye: 'Goodbye'
}
};