Intl.MessageFormat Introduction

2.5K Views

June 30, 23

スライド概要

Introducing Intl.MessageFormat proposal for ECMAScript (ECMA-402)
https://github.com/tc39/proposal-intl-messageformat

profile-image

Web Developer working on @kintone at @cybozu. Loves JavaScript and Curry! 🍛 Old slides: https://www.slideshare.net/teppeis/presentations

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

Intl.MessageFormat Introduction Teppei Sato (@teppeis) @Cybozu Frontend Day Jun 30, 2023 1

2.

Internationalization! 2

3.

ECMAScript has... • Intl.DateTimeFormat • Intl.NumberFormat • Intl.MessageFormat ← MISSING! 3

4.
[beta]
Usage
const format = new Intl.MessageFormat("{Hello {$place}!}");
const message = format.resolveMessage({ place: "world" });
message.toString(); // 'Hello world!'

4

5.

Status: Proposal Stage 1 • tc39/proposal-intl-messageformat • Designing "MessageFormat 2.0" with the Unicode Consortium's Message Format WG • Polyfill: npm i messageformat@next • This is implemented in ICU used internally by the browser and Node.js. 5

6.

MessageFormat 2.0 (aka "MF2") • A successor of ICU MessageFormat (20 years old popular API, used in FormatJS) • Expressive and clear like a programming language • Easy for developers, localization engineers and machines • Non-tech Translators expected to use GUI tools • For any languages and formats (XML, YAML, .properties...) • Not only for ECMAScript / JavaScript! 6

7.
[beta]
Simple Messages
All messages, including simple ones, need {…} delimiters:
{Hello, world!}

In message.properties file:
app.greetings.hello = {Hello, world!}

In JavaScript:
const hello = new MessageFormat("{Hello, world!}");
7

8.
[beta]
Simple Placeholders
{Hello, {$userName}!}

In JavaScript:
const format = new Intl.MessageFormat("{Hello, {$userName}!}");
const message = format.resolveMessage({ userName: "Teppei" });
message.toString(); // 'Hello, Teppei!'

8

9.
[beta]
Formatting Functions (:func)
• Built-in function
{Today is {$date :datetime weekday=long}.}
• Custom function
{Hello, {$userName :person case=vocative}!}
• Custom function with Object
{Hello, {$userObj :person firstName=long}!}
9

10.
[beta]
Markup Elements
The runtime can securely build a document tree structure.
{{+button}Submit{-button} or {+link}Cancel{-link}}

The runtime can output like:
<button>Submit</button> or <link>Cancel</link>

10

11.

Selection: Plurals match {$count :number} when 0 {You have no notifications.} when 1 {You have one notification.} when * {You have {$count} notifications.} 11

12.

Selection: Conditions match {:platform} when windows {Settings} when * {Preferences} 12

13.

Selection: Complex pattern matching match {$photoCount :number} {$userGender :equals} when 1 masculine {{$userName} added a new photo to his album.} when 1 feminine {{$userName} added a new photo to her album.} when 1 * {{$userName} added a new photo to their album.} when * masculine {{$userName} added {$photoCount} photos to his album.} when * feminine {{$userName} added {$photoCount} photos to her album.} when * * {{$userName} added {$photoCount} photos to their album.} 13

14.

Local Variables let $whom = {$monster :noun case=accusative} {You see {$quality :adjective article=indefinite accord=$whom} {$whom}!} 14

15.

Local Variables with Selection let $countInt = {$count :number maximumFractionDigits=0} let $itemAcc = {$item :noun count=$count case=accusative} match {$countInt} when one {You bought {$color :adjective article=indefinite accord=$itemAcc} {$itemAcc}.} when * {You bought {$countInt} {$color :adjective accord=$itemAcc} {$itemAcc}.} 15

16.

More Complex Message... let $hostName = {$host :person firstName=long} let $guestName = {$guest :person firstName=long} let $guestsOther = {$guestCount :number offset=1} match {$host :gender} {$guestOther :number} when when when when female female female female 0 1 2 * when when when when male male male male {{$hostName} {{$hostName} {{$hostName} {{$hostName} when when when when * * * * 0 1 2 * 0 1 2 * {{$hostName} {{$hostName} {{$hostName} {{$hostName} {{$hostName} {{$hostName} {{$hostName} {{$hostName} does not give a party.} invites {$guestName} to her party.} invites {$guestName} and one other person to her party.} invites {$guestName} and {$guestsOther} other people to her party.} does not give a party.} invites {$guestName} to his party.} invites {$guestName} and one other person to his party.} invites {$guestName} and {$guestsOther} other people to his party.} does not give a party.} invites {$guestName} to their party.} invites {$guestName} and one other person to their party.} invites {$guestName} and {$guestsOther} other people to their party.} 16

17.

Message Resource Bundle • Separated proposal: Intl.MessageFormat.parseResource() • tc39/proposal-intl-message-resource greeting = {Hello {$place}!} new_notifications = match {$count} when 0 {You have no new notifications} when one {You have {$count} new notification} when * {You have {$count} new notifications} 17

18.

Exciting! • This could be a standard used for all languages, translation tools and services. • Not only for ECMAScript / JavaScript • If you are looking to expand your product to the world, check it out! 18