Internationalization (i18n) of Meteor applications

Posted: , Modified:   Meteor i18n Angular
Copyright certificate by blockai

universe:i18n

How to internationalize Meteor application? An atmosphere package universe:i18n helps it. It supports locales in the list, and JSON and YAML formats for bilingual corpuses.

To install universe:i18n, run

$ meteor add universe:i18n

and add the following in script files to import it:

import i18n from "meteor/universe:i18n";

Register corpuses

You can add corpuses with APIs in universe:i18n. The following line adds a word associated with a namespace and a keyword to a locale.

i18n.addTranslation(“locale", “namespace", “keyword", “word");

Corpus file

It is hard to add corpuses by i18n.addTranslation function. You can add corpuses with JSON and YAML files, and such file names must end with .i18n.json and .i18n.yml, respectively.

For example, a YAML corpus file consists of key-value pairs such as

ok: 決定
cancel: キャンセル

You can specify namespace of a corpus file with adding _namespace key. The following example is a set of corpuses for namespace ui:

_namespace: ui
ok: 決定
cancel: キャンセル

Which locale a corpus file belongs to is specified by _locale key or file name. The following file belongs to locale ja

_locale: ja
ok: 決定
cancel: キャンセル

You need to open each corpus files to check locale if using _locale key. I think it is better to use file name to specify locale. For example, a corpus file which belongs to en-US locale should be following one of the two formats.

Note that corpus files must not be in imports directory.

Get a translated word

i18n.__(namespace, key) function returns a translated word associated with namespace and key.

i18n.__("ui", "ok"); // -> 決定 (in locale ja)

Change locale

i18n.setLocale("locale") function sets a new locale locale, and downloads the corpus associated with the locale asynchronously. The function returns a Promise and .then method is available to run some commands after receiving the corpus.

Use universe:i18n in Angular-Meteor

To use universe:i18n in Angular-Meteor template, add i18n.getTranslation method in a scope. Foe example, the following controller

class AppCtrl {

  constructor() {
    this.translator = i18n.getTranslation;
  }

}

provides translator method and a template

<md-button ng-click="$ctrl.onNext()" aria-label="$ctrl.translator('ui', 'ok')">
  {{$ctrl.translator("button", "start")}}
</md-button>

inserts a word associated with button namespace and start key. To update such words when locale is changed, use the following commands:

const setLocalePromise = i18n.setLocale(locale) || i18n.setLocale("en");
setLocalePromise.then((e) => {
   this.translator = i18n.getTranslation;
});

But if you call setLocale function without an UI event, for example in a constructor, DOM won’t be updated. You need to use $scope.$apply():

constructor($scope) {

  const setLocalePromise = i18n.setLocale(getLang()) || i18n.setLocale("en");
  setLocalePromise.then(() => {
    $scope.$apply( () =>{
      this.translator = i18n.getTranslation;
    });
  });

}

See AngularJS and scope.$apply for more information.