高级格式化

消息格式

基本的标记替换

Dojo 的 i18n 框架支持 ICU 消息格式化,也支持基本的标记替换。

接下来两个小节中的消息格式化示例会使用包含一个 guestInfo 消息的消息包,如下所示:

nls/main.ts

  1. export default {
  2. messages: {
  3. guestInfo: '{host} invites {guest} to the party.'
  4. }
  5. };

在部件中替换标记

支持 i18n 的部件可使用 i18n 中间件的 localize 方法返回的 format 函数在其消息中执行简单的标记替换。

可直接使用 format 渲染 guestInfo 消息:

widgets/MyI18nWidget.tsx

  1. import { create, tsx } from '@dojo/framework/core/vdom';
  2. import i18n from '@dojo/framework/core/middleware/i18n';
  3. import nlsBundle from '../nls/main';
  4. const factory = create({ i18n });
  5. export default factory(function MyI18nWidget({ middleware: { i18n } }) {
  6. const { format } = i18n.localize(nlsBundle);
  7. return (
  8. <div>
  9. {format('guestInfo', {
  10. host: 'Margaret Mead',
  11. guest: 'Laura Nader'
  12. })}
  13. </div>
  14. // Will render as 'Margaret Mead invites Laura Nader to the party.'
  15. );
  16. });

直接使用标记替换的格式化功能

i18n 模块的 localizeBundle 函数返回的对象中,有一个用于处理消息格式化的 format 方法:

  1. import { localizeBundle } from '@dojo/framework/i18n/i18n';
  2. import bundle from 'nls/main';
  3. localizeBundle(bundle, { locale: 'en' }).then(({ format }) => {
  4. const message = format('guestInfo', {
  5. host: 'Margaret Mead',
  6. guest: 'Laura Nader'
  7. });
  8. console.log(message); // "Margaret Mead invites Laura Nader to the party."
  9. });

ICU 消息格式化

@dojo/framework/i18n 使用 Globalize.js 进行 ICU 消息格式化,因此 Globalize.js 提供的所有功能都可以通过 @dojo/framework/i18n 访问。

接下来两个小节的消失格式化示例中将使用已更新了 guestInfo 消息的消息包,如下所示:

nls/main.ts

  1. export default {
  2. messages: {
  3. guestInfo: `{gender, select,
  4. female {
  5. {guestCount, plural, offset:1
  6. =0 {{host} does not give a party.}
  7. =1 {{host} invites {guest} to her party.}
  8. =2 {{host} invites {guest} and one other person to her party.}
  9. other {{host} invites {guest} and # other people to her party.}}}
  10. male {
  11. {guestCount, plural, offset:1
  12. =0 {{host} does not give a party.}
  13. =1 {{host} invites {guest} to his party.}
  14. =2 {{host} invites {guest} and one other person to his party.}
  15. other {{host} invites {guest} and # other people to his party.}}}
  16. other {
  17. {guestCount, plural, offset:1
  18. =0 {{host} does not give a party.}
  19. =1 {{host} invites {guest} to their party.}
  20. =2 {{host} invites {guest} and one other person to their party.}
  21. other {{host} invites {guest} and # other people to their party.}}}}`
  22. }
  23. };

在部件中使用 ICU 消息格式化功能

支持 i18n 的部件可使用 localizeBundle 方法返回的 format 函数来执行 ICU 消息格式化,这与上述的简单标记替换相同。

ICU 格式的 guestInfo 消息会被渲染为:

widgets/MyI18nWidget.tsx

  1. import { create, tsx } from '@dojo/framework/core/vdom';
  2. import i18n from '@dojo/framework/core/middleware/i18n';
  3. import nlsBundle from '../nls/main';
  4. const factory = create({ i18n });
  5. export default factory(function MyI18nWidget({ middleware: { i18n } }) {
  6. const { format } = i18n.localize(nlsBundle);
  7. return (
  8. <div>
  9. {
  10. format('guestInfo', {
  11. host: 'Margaret Mead',
  12. gender: 'female',
  13. guest: 'Laura Nader',
  14. guestCount: 20
  15. })
  16. }
  17. </div>
  18. ]); // Will render as 'Margaret Mead invites Laura Nader and 19 other people to her party.'
  19. );
  20. });

直接使用 ICU 消息格式化功能

可以使用 localizeBundle 返回的 format 方法直接转换 ICU 格式的 guestInfo 消息。

  1. import { localizeBundle } from '@dojo/framework/i18n/i18n';
  2. import bundle from 'nls/main';
  3. // 1. Load the messages for the locale.
  4. localizeBundle(bundle, { locale: 'en' }).then(({ format }) => {
  5. const message = format('guestInfo', {
  6. host: 'Margaret Mead',
  7. gender: 'female',
  8. guest: 'Laura Nader',
  9. guestCount: 20
  10. });
  11. console.log(message); // "Margaret Mead invites Laura Nader and 19 other people to her party."
  12. console.log(
  13. format('guestInfo', {
  14. host: 'Marshall Sahlins',
  15. gender: 'male',
  16. guest: 'Bronisław Malinowski'
  17. })
  18. ); // "Marshall Sahlins invites Bronisław Malinowski to his party."
  19. });

格式化日期和数字

跟文本消息格式化功能一样,@dojo/framework/i18n 使用 Globalize.js 为日期、时间、货币、数字和单位提供特定区域的格式化。格式化工具本身是对 Globalize.js 相应函数的轻量级封装,这有助于确保 Dojo 生态系统的一致性,并避免直接使用 Globalize 对象。与文本消息的格式化不同,日期、数字和单位格式化不会缓存,因为它们有一组更加复杂的选项。因此,多次使用相同的输入执行各种“获取格式化函数”的方法不会返回完全相同的函数对象。

@dojo/framework/i18n 对各种格式化函数进行分组:日期和时间格式化(@dojo/framework/i18n/date);数字、货币和多元化的格式化(@dojo/framework/i18n/number);单位格式化(@dojo/framework/i18n/unit)。每个方法都与 Globalize.js 中的方法一一对应(见下文),每个方法都遵循相同的基本格式:最后一个参数是可选的区域,倒数第二个参数是一个方法选项。如果指定了区域,但没有方法选项,则为 options 参数传入 null。如果没有提供区域设置,则假定使用当前区域(i18n.locale)。

  1. import { formatDate, getDateFormatter, formatRelativeTime } from '@dojo/framework/i18n/date';
  2. import { formatCurrency, getCurrencyFormatter } from '@dojo/framework/i18n/number';
  3. import { formatUnit, getUnitFormatter } from '@dojo/framework/i18n/unit';
  4. const date = new Date(1815, 11, 10, 11, 27);
  5. // Assume the current locale is "en"
  6. const enDateFormatter = getDateFormatter({ datetime: 'medium' });
  7. enDateFormatter(date); // Dec 10, 1815, 11:27:00 AM
  8. formatDate(date, { date: 'short' }); // 12/10/15
  9. const frDateFormatter = getDateFormatter({ datetime: 'medium' }, 'fr');
  10. frDateFormatter(date); // 10 déc. 1815 à 11:27:00
  11. formatDate(date, { date: 'short' }, 'fr'); // 10/12/1815
  12. formatRelativeTime(-1, 'week'); // "last week"
  13. formatRelativeTime(-1, 'week', { form: 'short' }); // "last wk."
  14. formatRelativeTime(-3, 'week', null, 'fr'); // "il y a 3 semaines"
  15. formatRelativeTime(-3, 'week', { form: 'short' }, 'fr'); // "il y a 3 sem."
  16. const enCurrencyFormatter = getCurrencyFormatter('USD', { style: 'code' });
  17. enCurrencyFormatter(1234.56); // "1,234.56 USD"
  18. formatCurrency(12345.56, 'USD', { style: 'code' }); // "1,234.56 USD"
  19. const frCurrencyFormatter = getCurrencyFormatter('EUR', { style: 'code' }, 'fr');
  20. frCurrencyFormatter(1234.56); // "1 234,56 EUR"
  21. formatCurrency(12345.56, 'EUR', { style: 'code' }, 'fr'); // "1 234,56 EUR"
  22. const enUnitFormatter = getUnitFormatter('feet', { form: 'narrow' });
  23. enUnitFormatter(5280); // 5,280′
  24. formatUnit(5280, 'feet', { form: 'narrow' }); // 5,280′
  25. const frUnitFormatter = getUnitFormatter('meter', null, 'fr');
  26. frUnitFormatter(1000); // 1 000 mètres'
  27. formatUnit(1000, 'meter', null, 'fr); // 1 000 mètres'

@dojo/framework/i18n/date 方法:

@dojo/framework/i18n/number 方法:

@dojo/framework/i18n/unit 方法: