Skip to content

Instantly share code, notes, and snippets.

@stasm
Last active October 15, 2023 11:40
Show Gist options
  • Save stasm/acb6b691e674f43f689014912fce8cfb to your computer and use it in GitHub Desktop.
Save stasm/acb6b691e674f43f689014912fce8cfb to your computer and use it in GitHub Desktop.
MessageFormat Beauty Contest

When evaluating each option below, please keep in mind the following questions:

  1. What's going on in the examples? What's your first reaction to seeing them?
  2. What do you like about each example? Any good ideas worth transplanting to other options? Feel free to mix and match.
  3. What do you dislike about each example? Imagine you have to work with this syntax in the future (it will one day be available directly in JavaScript!). What do you thikn is going to be annoying?
  4. What do you think the output of help, hello and notif is exactly (including leading and trailing whitespace)?
  5. How would you add a single space in front of all presented messages, to make it part of the translatable text?
  6. How would you add a newline in front of all presented messages, to make it part of the translatable text?

In option A, all messages are always surrounded by a pair of curly braces, {...}.


MessageFormat strings can be used directly in code to interpolate data inside text in a locale-aware manner. Tooling can then be built to extract such strings into translatable resources. The following snippet uses a proposed stage-1 Intl.MessageFormat API.

let help = new Intl.MessageFormat("en", "{Get Support}");
document.body.textContent = help.format();

let hello = new Intl.MessageFormat("en", "{Hello, {$username}!}");
alert(hello.format({username: "Anne"}));

function showNotificationCount(count = 3) {
    let notif = new Intl.MessageFormat("en", `
        match {$count :plural}
        when 1 {You have one new message.}
        when * {You have {$count} new messages.}
    `);
    alert(notif.format({count}));
}

Translatable messages can be extracted or manually put into some kind of storage: a DB, a spreadsheet, or a JSON file:

{
    "help": "{Get Support}",
    "hello": "{Hello, {$username}!}",
    "notif": "match {$count :plural} when 1 {You have one new message.} when * {You have {$count} new messages.}"
}

There's also an early ongoing work on a special-purpose resource file format for messages. Perhaps something like this:

help = {Get Support}
hello = {Hello, {$username}!}
notif =
    match {$count :plural}
    when 1 {You have one new message.}
    when * {You have {$count} new messages.}

In option B, text is not delimited, but statements and expressions are, by {% ... %} and {{ ... }} respectively.


MessageFormat strings can be used directly in code to interpolate data inside text in a locale-aware manner. Tooling can then be built to extract such strings into translatable resources. The following snippet uses a proposed stage-1 Intl.MessageFormat API.

let help = new Intl.MessageFormat("en", "Get Support");
document.body.textContent = help.format();

let hello = new Intl.MessageFormat("en", "Hello, {{$username}}!");
alert(hello.format({username: "Anne"}));

function showNotificationCount(count = 3) {
    let notif = new Intl.MessageFormat("en", `
        {% match {$count :plural} %}
        {% when 1 %} You have one new message.
        {% when * %} You have {{$count}} new messages.
    `);
    alert(notif.format({count}));
}

Translatable messages can be extracted or manually put into some kind of storage: a DB, a spreadsheet, or a JSON file:

{
    "help": "Get Support",
    "hello": "Hello, {{$username}}!",
    "notif": "{% match {$count :plural} %} {% when 1 %} You have one new message. {% when %} You have {{$count}} new messages."
}

There's also an early ongoing work on a special-purpose resource file format for messages. Perhaps something like this:

help = Get Support
hello = Hello, {{$username}}!
notif =
    {% match {$count :plural} %}
    {% when 1 %} You have one new message.
    {% when * %} You have {{$count}} new messages.

Option C is similar to option A, but simple messages don't have to be delimited by curly braces. Compare: Get Support vs. option A's {Get Support}. OTOH, more complex messages must be wrapped in {{ ... }}, e.g. {{ match ... when ... when ... }}.


MessageFormat strings can be used directly in code to interpolate data inside text in a locale-aware manner. Tooling can then be built to extract such strings into translatable resources. The following snippet uses a proposed stage-1 Intl.MessageFormat API.

let help = new Intl.MessageFormat("en", "Get Support");
document.body.textContent = help.format();

let hello = new Intl.MessageFormat("en", "Hello, {$username}!");
alert(hello.format({username: "Anne"}));

function showNotificationCount(count = 3) {
    let notif = new Intl.MessageFormat("en", `
        {{ match {$count :plural}
           when 1 {You have one new message.}
           when * {You have {$count} new messages.}
        }}
    `);
    alert(notif.format({count}));
}

Translatable messages can be extracted or manually put into some kind of storage: a DB, a spreadsheet, or a JSON file:

{
    "help": "Get Support",
    "hello": "Hello, {$username}!",
    "notif": "{{match {$count :plural} when 1 {You have one new message.} when * {You have {$count} new messages.}}}"
}

There's also an early ongoing work on a special-purpose resource file format for messages. Perhaps something like this:

help = Get Support
hello = Hello, {$username}!
notif = {{
    match {$count :plural}
    when 1 {You have one new message.}
    when * {You have {$count} new messages.}
}}

Option D is similar to option B: text is not delimited, but statements and expressions are. The syntax is slightly different, however:

  • {#match ... } instead of option B's {% match ... %},
  • {#when ... } instead of option B's {% when ... %},
  • {$username} instead of option B's {{ $username }},

MessageFormat strings can be used directly in code to interpolate data inside text in a locale-aware manner. Tooling can then be built to extract such strings into translatable resources. The following snippet uses a proposed stage-1 Intl.MessageFormat API.

let help = new Intl.MessageFormat("en", "Get Support");
document.body.textContent = help.format();

let hello = new Intl.MessageFormat("en", "Hello, {$username}!");
alert(hello.format({username: "Anne"}));

function showNotificationCount(count = 3) {
    let notif = new Intl.MessageFormat("en", `
        {#match {$count :plural}}
        {#when 1} You have one new message.
        {#when *} You have {$count} new messages.
    `);
    alert(notif.format({count}));
}

Translatable messages can be extracted or manually put into some kind of storage: a DB, a spreadsheet, or a JSON file:

{
    "help": "Get Support",
    "hello": "Hello, {$username}!",
    "notif": "{#match {$count :plural}} {#when 1} You have one new message. {#when *} You have {$count} new messages."
}

There's also an early ongoing work on a special-purpose resource file format for messages. Perhaps something like this:

help = Get Support
hello = Hello, {$username}!
notif =
    {#match {$count :plural}}
    {#when 1} You have one new message.
    {#when *} You have {$count} new messages.

In option E, text is not delimited, but statements and expressions are, by #[ ... ] and { ... } respectively. This is similar to option B and D, but uses square brackets for statements. Also, there's no when, so {% when 1 %} becomes #[1].


MessageFormat strings can be used directly in code to interpolate data inside text in a locale-aware manner. Tooling can then be built to extract such strings into translatable resources. The following snippet uses a proposed stage-1 Intl.MessageFormat API.

let help = new Intl.MessageFormat("en", "Get Support");
document.body.textContent = help.format();

let hello = new Intl.MessageFormat("en", "Hello, {$username}!");
alert(hello.format({username: "Anne"}));

function showNotificationCount(count = 3) {
    let notif = new Intl.MessageFormat("en", `
        #[match {$count :plural}]
        #[1] You have one new message.
        #[*] You have {$count} new messages.
    `);
    alert(notif.format({count}));
}

Translatable messages can be extracted or manually put into some kind of storage: a DB, a spreadsheet, or a JSON file:

{
    "help": "Get Support",
    "hello": "Hello, {$username}!",
    "notif": "#[match {$count :plural}] #[1] You have one new message. #[*] You have {$count} new messages."
}

There's also an early ongoing work on a special-purpose resource file format for messages. Perhaps something like this:

help = Get Support
hello = Hello, {$username}!
notif =
    #[match {$count :plural}]
    #[1] You have one new message.
    #[*] You have {$count} new messages.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment