【前端国际化】ICU消息格式:处理复杂翻译场景
【前端国际化】ICU消息格式处理复杂翻译场景前言大家好我是cannonmonster01上一篇我们聊了i18next的基本用法今天咱们来深入聊聊ICU消息格式。如果你曾经遇到过复数处理、性别差异、日期格式化等复杂翻译场景那么ICU消息格式就是你的救星什么是ICU消息格式ICUInternational Components for Unicode是一套国际化支持库ICU消息格式是其中的核心部分。它提供了一种强大的方式来处理复杂的翻译场景复数形式Plurals性别形式Gender选择形式Select格式化Formatting嵌套消息NestedICU消息格式的语法基本语法{占位符名, 类型, 格式}数据类型类型说明示例number数字格式化{count, number}date日期格式化{date, date}time时间格式化{time, time}plural复数处理{count, plural, one {...} other {...}}select选择处理{gender, select, male {...} female {...} other {...}}selectordinal序数处理{rank, selectordinal, one {...} two {...}}复数处理基本用法// 翻译字符串 const message {count, plural, one {1 item} other {{count} items}}; // 使用 formatMessage(message, { count: 1 }); // 1 item formatMessage(message, { count: 5 }); // 5 items复数类别不同语言有不同的复数规则// 英语one, other {count, plural, zero {No items} one {1 item} two {2 items} few {A few items} many {Many items} other {{count} items} }实际示例{ items: {count, plural, one {1件商品} other {{count}件商品}}, apples: {count, plural, zero {没有苹果} one {1个苹果} other {{count}个苹果}}, visitors: {count, plural, one {一位访客} other {{count}位访客}} }性别处理基本用法const message {gender, select, male {他} female {她} other {他们}}; formatMessage(message, { gender: male }); // 他 formatMessage(message, { gender: female }); // 她 formatMessage(message, { gender: other }); // 他们组合使用const message {gender, select, male {他有 {count, plural, one {1个苹果} other {{count}个苹果}} } female {她有 {count, plural, one {1个苹果} other {{count}个苹果}} } other {他们有 {count, plural, one {1个苹果} other {{count}个苹果}} } }; formatMessage(message, { gender: male, count: 5 }); // 他有5个苹果选择处理基本用法const message {role, select, admin {管理员} user {普通用户} guest {访客}}; formatMessage(message, { role: admin }); // 管理员 formatMessage(message, { role: user }); // 普通用户复杂示例{ accessLevel: {level, select, guest {访客权限 - 仅可浏览} user {用户权限 - 可编辑} admin {管理员权限 - 完全控制} superadmin {超级管理员 - 所有权限} } }格式化处理数字格式化// 基本数字 {price, number} // 1234.56 {price, number, integer} // 1235 {price, number, percent} // 123456% {price, number, currency} // $1,234.56 {price, number, #,##0.00} // 1,234.56日期格式化// 日期格式 {date, date} // 2024/01/15 {date, date, short} // 1/15/24 {date, date, medium} // Jan 15, 2024 {date, date, long} // January 15, 2024 {date, date, full} // Monday, January 15, 2024 {date, date, year} // 2024 {date, date, month} // January {date, date, day} // 15时间格式化// 时间格式 {time, time} // 10:30:00 AM {time, time, short} // 10:30 AM {time, time, medium} // 10:30:00 AM {time, time, long} // 10:30:00 AM GMT8嵌套消息基本嵌套const message 欢迎{name}加入我们的社区您是第{count, plural, one {1位} other {{count}位}}成员。; formatMessage(message, { name: 小明, count: 100 }); // 欢迎小明加入我们的社区您是第100位成员。多层嵌套const message {gender, select, male {他是第 {rank, selectordinal, one {一} two {二} other {{rank}}} 位用户} female {她是第 {rank, selectordinal, one {一} two {二} other {{rank}}} 位用户} other {他们是第 {rank, selectordinal, one {一} two {二} other {{rank}}} 位用户} };在i18next中使用ICU安装插件npm install i18next-icu配置import i18n from i18next; import ICU from i18next-icu; import { initReactI18next } from react-i18next; i18n .use(ICU) .use(initReactI18next) .init({ fallbackLng: zh, interpolation: { escapeValue: false } });使用示例// locales/zh/common.json { items: {count, plural, one {1件商品} other {{count}件商品}}, welcome: 欢迎{name}今天是{date, date, long}。, balance: 您的余额是{amount, number, currency}。 }import { useTranslation } from react-i18next; const Component () { const { t } useTranslation(); return ( div p{t(items, { count: 5 })}/p p{t(welcome, { name: 小明, date: new Date() })}/p p{t(balance, { amount: 1234.56 })}/p /div ); };在Vue中使用ICUimport { createI18n } from vue-i18n; import { ICUMessageFormatPlugin } from vue/composition-api; const i18n createI18n({ legacy: false, locale: zh, fallbackLocale: zh, messages: { zh: { items: {count, plural, one {1件商品} other {{count}件商品}} }, en: { items: {count, plural, one {1 item} other {{count} items}} } }, plugins: [ICUMessageFormatPlugin] });复数规则详解CLDR复数类别类别说明适用语言zero零阿拉伯语等one一英语、法语等two二阿拉伯语、威尔士语few少数俄语、波兰语等many多数阿拉伯语、希腊语等other其他所有语言英语复数规则// 英语1用one其他用other {count, plural, one {1 item} other {{count} items}}俄语复数规则// 俄语1用one2-4用few其他用many {count, plural, one {{count} предмет} few {{count} предмета} many {{count} предметов}}中文复数规则// 中文通常不需要复数变化 {count, plural, other {{count}件商品}}最佳实践保持翻译简洁// 好的示例 {count, plural, one {1个苹果} other {{count}个苹果}} // 避免重复 {count, plural, one {有1个苹果} other {有{count}个苹果}}使用默认值// 提供默认值 {name, select, male {他} female {她} other {用户}}测试各种场景// 测试边界情况 test(复数处理, () { expect(formatMessage({count, plural, one {1} other {{count}}}, { count: 0 })).toBe(0); expect(formatMessage({count, plural, one {1} other {{count}}}, { count: 1 })).toBe(1); expect(formatMessage({count, plural, one {1} other {{count}}}, { count: 100 })).toBe(100); });工具支持ICU Message Editor这是一个在线工具可以帮助你编写和测试ICU消息格式官网https://format-message.github.io/icu-message-editor/i18next-parser配置module.exports { options: { interpolation: { formatSeparator: , }, parseICU: true } };总结ICU消息格式是处理复杂翻译场景的利器通过今天的学习相信你已经掌握了ICU消息格式的基本语法复数处理的用法性别和选择处理日期和数字格式化嵌套消息的使用在i18next和Vue中的集成掌握ICU消息格式让你的国际化应用更加专业和完善