Skip to content

Instantly share code, notes, and snippets.

@filipef101
Created February 28, 2018 23:14
Show Gist options
  • Save filipef101/d4c7c0489e51e36814a3c14214927be2 to your computer and use it in GitHub Desktop.
Save filipef101/d4c7c0489e51e36814a3c14214927be2 to your computer and use it in GitHub Desktop.

You can use translate your messages:

I18n.t("some.scoped.translation");
// or translate with explicit setting of locale
I18n.t("some.scoped.translation", {locale: "fr"});

You can also interpolate values:

I18n.t("hello", {name: "John Doe"});

You can set default values for missing scopes:

// simple translation
I18n.t("some.missing.scope", {defaultValue: "A default message"});

// with interpolation

I18n.t("noun", {defaultValue: "I'm a {{noun}}", noun: "Mac"});

Very useful ex> in translation {someValue: "I'm a {{noun}}"}

I18n.t("someValue", {noun: "Mac"});

// As a simple translation I18n.t("some.missing.scope", {defaults: [{message: "Some message"}]});


By default missing translations will first be looked for in less
specific versions of the requested locale and if that fails by taking
them from your `I18n.defaultLocale`.

```javascript
// if I18n.defaultLocale = "en" and translation doesn't exist
// for I18n.locale = "de-DE" this key will be taken from "de" locale scope
// or, if that also doesn't exist, from "en" locale scope
I18n.t("some.missing.scope");

Custom fallback rules can also be specified for a particular language. There are three different ways of doing it so:

I18n.locales.no = ["nb", "en"];
I18n.locales.no = "nb";
I18n.locales.no = function(locale){ return ["nb"]; };

And result will be:

"EE: what is your favorite Christmas present"

This will help you doing automated tests against your localisation assets.

Some people prefer returning null for missing translation:

I18n.missingTranslation = function () { return undefined; };

Pluralization is possible as well and by default provides English rules:

I18n.t("inbox.counting", {count: 10}); // You have 10 messages

The sample above expects the following translation:

en:
  inbox:
    counting:
      one: You have 1 new message
      other: You have {{count}} new messages
      zero: You have no messages

NOTE: Rails I18n recognizes the zero option.

If you need special rules just define them for your language, for example Russian, just add a new pluralizer:

I18n.pluralization["ru"] = function (count) {
  var key = count % 10 == 1 && count % 100 != 11 ? "one" : [2, 3, 4].indexOf(count % 10) >= 0 && [12, 13, 14].indexOf(count % 100) < 0 ? "few" : count % 10 == 0 || [5, 6, 7, 8, 9].indexOf(count % 10) >= 0 || [11, 12, 13, 14].indexOf(count % 100) >= 0 ? "many" : "other";
  return [key];
};

You can find all rules on http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html.

If you're using the same scope over and over again, you may use the scope option.

var options = {scope: "activerecord.attributes.user"};

I18n.t("name", options);
I18n.t("email", options);
I18n.t("username", options);

You can also provide an array as scope.

// use the greetings.hello scope
I18n.t(["greetings", "hello"]);

Number formatting

Similar to Rails helpers, you have localized number and currency formatting.

I18n.l("currency", 1990.99);
// $1,990.99

I18n.l("number", 1990.99);
// 1,990.99

I18n.l("percentage", 123.45);
// 123.450%

To have more control over number formatting, you can use the I18n.toNumber, I18n.toPercentage, I18n.toCurrency and I18n.toHumanSize functions.

I18n.toNumber(1000);     // 1,000.000
I18n.toCurrency(1000);   // $1,000.00
I18n.toPercentage(100);  // 100.000%

The toNumber and toPercentage functions accept the following options:

  • precision: defaults to 3
  • separator: defaults to .
  • delimiter: defaults to ,
  • strip_insignificant_zeros: defaults to false

See some number formatting examples:

I18n.toNumber(1000, {precision: 0});                   // 1,000
I18n.toNumber(1000, {delimiter: ".", separator: ","}); // 1.000,000
I18n.toNumber(1000, {delimiter: ".", precision: 0});   // 1.000

The toCurrency function accepts the following options:

  • precision: sets the level of precision
  • separator: sets the separator between the units
  • delimiter: sets the thousands delimiter
  • format: sets the format of the output string
  • unit: sets the denomination of the currency
  • strip_insignificant_zeros: defaults to false
  • sign_first: defaults to true

You can provide only the options you want to override:

I18n.toCurrency(1000, {precision: 0}); // $1,000

The toHumanSize function accepts the following options:

  • precision: defaults to 1
  • separator: defaults to .
  • delimiter: defaults to ""
  • strip_insignificant_zeros: defaults to false
  • format: defaults to %n%u
I18n.toHumanSize(1234); // 1KB
I18n.toHumanSize(1234 * 1024); // 1MB

Date formatting

// accepted formats
I18n.l("date.formats.short", "2009-09-18");           // yyyy-mm-dd
I18n.l("time.formats.short", "2009-09-18 23:12:43");  // yyyy-mm-dd hh:mm:ss
I18n.l("time.formats.short", "2009-11-09T18:10:34");  // JSON format with local Timezone (part of ISO-8601)
I18n.l("time.formats.short", "2009-11-09T18:10:34Z"); // JSON format in UTC (part of ISO-8601)
I18n.l("date.formats.short", 1251862029000);          // Epoch time
I18n.l("date.formats.short", "09/18/2009");           // mm/dd/yyyy
I18n.l("date.formats.short", (new Date()));           // Date object

You can also add placeholders to the date format:

I18n.translations["en"] = {
  date: {
    formats: {
      ordinal_day: "%B %{day}"
    }
  }
}
I18n.l("date.formats.ordinal_day", "2009-09-18", { day: '18th' }); // Sep 18th

If you prefer, you can use the I18n.strftime function to format dates.

var date = new Date();
I18n.strftime(date, "%d/%m/%Y");

The accepted formats are:

%a  - The abbreviated weekday name (Sun)
%A  - The full weekday name (Sunday)
%b  - The abbreviated month name (Jan)
%B  - The full month name (January)
%d  - Day of the month (01..31)
%-d - Day of the month (1..31)
%H  - Hour of the day, 24-hour clock (00..23)
%-H - Hour of the day, 24-hour clock (0..23)
%I  - Hour of the day, 12-hour clock (01..12)
%-I - Hour of the day, 12-hour clock (1..12)
%m  - Month of the year (01..12)
%-m - Month of the year (1..12)
%M  - Minute of the hour (00..59)
%-M - Minute of the hour (0..59)
%p  - Meridian indicator (AM  or  PM)
%S  - Second of the minute (00..60)
%-S - Second of the minute (0..60)
%w  - Day of the week (Sunday is 0, 0..6)
%y  - Year without a century (00..99)
%-y - Year without a century (0..99)
%Y  - Year with century
%z  - Timezone offset (+0545)

Check out spec/*.spec.js files for more examples!

Using pluralization and number formatting together

Sometimes you might want to display translation with formatted number, like adding thousand delimiters to displayed number
You can do this:

{
  "en": {
    "point": {
      "one": "1 Point",
      "other": "{{formatted_number}} Points",
      "zero": "0 Points"
    }
  }
}
var point_in_number = 1000;
I18n.t('point', { count: point_in_number, formatted_number: I18n.toNumber(point_in_number) });

Output should be 1,000 points

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment