Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Internationali[sz]ation: 
It's easy in Ember!

Internationali[sz]ation: 
It's easy in Ember!

Tobias Bieniek

September 21, 2018
Tweet

More Decks by Tobias Bieniek

Other Decks in Programming

Transcript

  1. Plurals zero 0 one 1 two 2 few 3-10, 103-110,

    ... many 11-99, 111-199, ... other 100-102, 200-202, ... * http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html
  2. Units 1 league = 3 miles 1 mile = 5,280

    feet 1 yard = 3 feet 1 foot = 12 inches 1 inch = 1
  3. ... is the design and development of a product that

    
 enables easy localization for target audiences that 
 vary in culture, region, or language. I18n: Internationalization https://blog.mozilla.org/l10n/2011/12/14/i18n-vs-l10n-whats-the-diff/
  4. ... refers to the adaptation of a product to
 meet

    the language, cultural and other
 requirements of a specific target market. L10n: Localization https://blog.mozilla.org/l10n/2011/12/14/i18n-vs-l10n-whats-the-diff/
  5. Internationalization: what developers work on Localization: what translators work on

    Internationalization enables Localization tl;dr https://blog.mozilla.org/l10n/2011/12/14/i18n-vs-l10n-whats-the-diff/
  6. a set of parameters that defines the user's language, region

    and any special variant preferences that the user wants to see in their user interface. Locale https://en.wikipedia.org/wiki/Locale_(computer_software)
  7. pt-BR Brazilian Portuguese en English zh-Hans-HK Hong Kong Chinese in

    simplified script BCP 47 Language Script Region
  8. Locale Defaults de $ de-Latn-DE es 0 es-Latn-ES en "

    en-Latn-US pt 3 pt-Latn-BR zh + zh-Hans-CN https://github.com/unicode-cldr/cldr-core/blob/33.0.0/supplemental/likelySubtags.json
  9. let numberFormat = new Intl.NumberFormat('en-IN', { style: 'currency', currency: 'EUR',

    }); let formattedNumber = numberFormat.format(123456.789); // 123.456,79 € Intl.NumberFormat
  10. let date = new Date(2018, 8, 21, 12, 0, 0);

    new Intl.DateTimeFormat('en-US').format(date); // 09/21/2018 new Intl.DateTimeFormat('de-DE').format(date); // 21.09.2018 Intl.DateFormat
  11. He has 5 apples and one tomato. She has one

    apple and no tomatoes. They have no apples and 101 tomatoes. dynamic static
  12. {GENDER, select, male {He has} female {She has} other {They

    have} } {APPLES, plural, =0 {no apples} one {one apple} other {# apples} } and {TOMATOES, plural, =0 {no tomatoes} one {one tomato} other {# tomatoes} }. ICU
  13. {GENDER, select, male {He has} female {She has} other {They

    have} } {APPLES, plural, =0 {no apples} one {one apple} other {# apples} } and {TOMATOES, plural, =0 {no tomatoes} one {one tomato} other {# tomatoes} }. ICU t('apple-and-tomatoes', { GENDER: 'male', APPLES: 5, TOMATOES: 0, }); // He has 5 apples // and no tomatoes
  14. Basic Setup app/route/application.js: intl: service(), beforeModel() { let locale =

    figureOutLocale(); // e.g. 'en' this.intl.set('locale', locale); }
  15. Translations this.intl.t('my-name-is', { name: 'Robert Jackson' }); // Ich heiße

    Robert Jackson {{t "my-name-is" name="Robert Jackson"}} <!-- Ich heiße Robert Jackson -->
  16. Async Loading $ ls translations/ total 4864 -rw-r --r --

    1 tbieniek staff 129K 12 Sep 11:28 cs.yml -rw-r --r -- 1 tbieniek staff 123K 12 Sep 11:28 da.yml -rw-r --r -- 1 tbieniek staff 127K 12 Sep 11:28 de-at.yml -rw-r --r -- 1 tbieniek staff 129K 12 Sep 11:28 de-ch.yml -rw-r --r -- 1 tbieniek staff 128K 12 Sep 11:28 de.yml -rw-r --r -- 1 tbieniek staff 122K 12 Sep 11:28 en-at.yml -rw-r --r -- 1 tbieniek staff 123K 12 Sep 11:28 en.yml -rw-r --r -- 1 tbieniek staff 124K 12 Sep 11:28 es.yml -rw-r --r -- 1 tbieniek staff 129K 12 Sep 11:28 fr-ch.yml -rw-r --r -- 1 tbieniek staff 130K 12 Sep 11:28 fr.yml ...
  17. Async Loading async beforeModel() { let locale = figureOutLocale(); let

    translations = await loadTranslations(locale); this.intl.addTranslations(locale, translations); this.intl.set('locale', locale); }
  18. Async Loading config/ember-intl.js: publicOnly: true $ ls dist/assets/translations/ total 6488

    -rw-r --r -- 1 tbieniek staff 174K 11 Sep 15:49 cs.json -rw-r --r -- 1 tbieniek staff 166K 11 Sep 15:49 da.json -rw-r --r -- 1 tbieniek staff 170K 11 Sep 15:49 de-at.json -rw-r --r -- 1 tbieniek staff 171K 11 Sep 15:49 de-ch.json -rw-r --r -- 1 tbieniek staff 169K 11 Sep 15:49 de.json -rw-r --r -- 1 tbieniek staff 163K 11 Sep 15:49 en-at.json
  19. Async Loading async loadTranslations(locale) { let response = await fetch(

    `/assets/translations/${locale}.json` ); let translations = await response.json(); return translations; }
  20. <a href={{pilotHref}}>{{pilotName}} </a> uploaded a {{distance}} flight on {{date}}. {{t

    "event.flight-upload" pilotName=flight.pilot.name pilotHref=flight.pilot.url distance=(format-distance flight.distance) date=(format-date flight.date) htmlSafe=true }}