-
Notifications
You must be signed in to change notification settings - Fork 589
Support ICU MessageFormat #265
Description
PR: #321
Globalize.formatMessage() should support Message Format as in ICU.
Globalize.loadMessages({
"en": {
like: "{count, plural, offset:1" +
" =0 {Be the first to like this}" +
" =1 {You liked this}" +
" one {You and someone else liked this}" +
"other {You and # others liked this}" +
"}",
task: "You have {count, plural," +
" one {one task}" +
"other {# tasks}" +
"} remaining"
}
});
var en = new Globalize( "en" );
en.formatMessage( "task", { count: 0 } ); // You have 0 tasks.
en.formatMessage( "task", { count: 1 } ); // You have 1 task.
var likeFormatter = en.messageFormatter( "like" );
[ 0, 1, 2, 3 ].map(function( count ) {
return taskFormatter({ count: count });
});
// [
// "Be the first to like this",
// "You liked this",
// "You and someone else liked this",
// "You and 2 others liked this"
// ]For background purposes...
The original issue has been opened as "Basic .formatMessage()". The goal was to discuss whether or not we should implement a basic .formatMessage() that would reside in globalize.js (core). For a MessageFormat extension, one would load globalize/message.js module.
The discussion here has diverged into Message Format specifics... Considering this discussion has great value and the basic formatMessage has been implemented internally due to #251, I have renamed this issue to "Support MessageFormat".
Follow the original issue description:
We currently have two "message" functions: .loadTranslations( translationData ) and .translate( path ).
While they're useful for translations, it doesn't provide any value for formatting messages, eg. variable replacements, plural or select formatting.
😄
Globalize( "en" ).translate( "bye" ); // bye
Globalize( "pt" ).translate( "bye" ); // tchau
// Obviously, considering the appropriate translate values have been loaded.😭
Globalize.???( "{0} seconds", 4 ); // 4 seconds
Globalize.???( "{0, plural, one {{0} second} other {{0} seconds}}", 4 ); // 4 seconds
Globalize.???( "{0, select, male {He} female {She}} waited for {1, plural, one {{1} second} other {{1} seconds}}", 4 ); // He waited for 4 secondsPlural and select formatting requires a parser. But, the variable replacement of the 4 seconds example is easily implementable and is needed in several parts of CLDR.
Given the easiness and necessity of variable replacement and all the above context, I suggest we implement:
.formatMessage( message, data );
.formatMessage( "{0} second", 1 ); // 1 second
.formatMessage( "{0}/{1}", ["m", "s"] ); // m/s
.formatMessage( "{name} <{email}>", {
name: "Foo",
email: "bar@baz.qux"
}); // Foo <bar@baz.qux>The above implementation plus the translation functions have a minified size of ~0.7Kb. Given its size, I want to include all the three functions (loadTranslations(), translate(), and formatMessage() the simple version) in the Core module.
If user needs to format more complex messages, eg. plural or select formatting, he can load plural or other modules and extend the simple .formatMessage() above.