Goldstone i18n (internationalization) scheme

This document describes:

This document assumes you have installed Goldstone according to the HACKING.md document, and have node/npm installed.

Make sure your dev environment is up to date with the latest npm dependencies with:

$ npm install

Please keep in mind that there is no direct relationship between .po files (which are standard for gettext), and JavaScript. For changes in .po files in goldstone/static/i18n/po_files to affect the client rendering, you have to make sure that modifications are made while the Grunt.js task runner is operating by running grunt watch in a terminal tab. Alternately you could run grunt po2json from the terminal after making changes to a .po file.

How i18n is implemented in the Goldstone client.

The Goldstone i18n scheme is based on the gettext standard, which is a very common method of internationalizing an app, and with which many translators are already familiar. Tools and libraries are available so that the same .po files can be applied to client and server environments. Goldstone uses a popular library, Jed.js, to make available the gettext functions. And to make the .po files readable by Jed.js, we chose the recommended adjunct library, po2json which makes for a Jed.js-readable json object.

With the grunt watch environment running, any additions of new .po files, or modification of existing .po files will trigger a Grunt task called po2json that will create a new json object that will be served by Django, and made available to the JavaScript client.

With each browser page refresh, the client initialization process includes parsing the translated i18n json object, and making it readable by the Jed.js library that adapts the standard gettext functions for JavaScript.

How to import a new .po file into the front-end i18n scheme so it's available as a selection in the client.

When adding a new .po file, remember that the file's name prior to the .po (eg: Latin from Latin.po) will be used to dynamically populate the language choices in the client's settings page. Capitalization will be carried over, so be sure to name your .po file exactly as you'd like to see it as a language choice.

Adding a file to or changing a file in goldstone/static/i18n/po_files (with the grunt watch task running) will trigger a re-rendering of goldstone/static/i18n/po_json/i18n_combined.json. This file is used by the Jed.js library as described in the section above.

The gettext functions that have been wrapped in the goldstone namespace at this time are:

  • dgettext (translate a string in the context of a particular domain) via goldstone.translate(string)
  • dpgettext (translate a string in the context of a particular domain, with an additional context specifier) via goldstone.contextTranslate(string, context)
  • sprintf (string interpolation) via goldstone.sprintf('hello %s', 'world')

Additional getttext functions are available as part of: goldstone.translationObject

For example, if you had a particular need to implement a lookup with dnpgettext (domain, number, plural), you could do so with goldstone.translationObject.dnpgettext(domain, context, singular_key, plural_key, value).

The full range of combos, as documented by Jed.js, are as follows:

gettext = function ( key )
dgettext = function ( domain, key )
dcgettext = function ( domain, key, category )
ngettext = function ( singular_key, plural_key, value )
dngettext = function ( domain, singular_ley, plural_key, value )
dcngettext = function ( domain, singular_key, plural_key, value, category )
pgettext = function ( context, key )
dpgettext = function ( domain, context, key )
npgettext = function ( context, singular_key, plural_key, value )
dnpgettext = function ( domain, context, singular_key, plural_key, value )
dcnpgettext = function ( domain, context, singular_key, plural_key, value, category )

Any of the above can be called via goldstone.translationObject.[gettext function from list above](function signature)

How to implement i18n client-side so that the text strings of your choice are translated to the user-selected language.

Basic translation

In your .po file:

msgid "How are you?"
msgstr "¿Cómo Está?"

goldstone.translate('How are you?') => returns '¿Cómo Está?'

With context modifier

In your .po file:

msgid "How are you?"
msgstr "¿Cómo Está?"

msgctxt "red herrings"
msgid "How are you?"
msgstr "¿How art thou?"

goldstone.contextTranslate('How are you?', 'red herrings') => returns '¿How art thou?'

while...

goldstone.translate('How are you?') => returns '¿Cómo Está?'

In your .po file:

msgid "How are you?"
msgstr "¿Cómo Está?"

<span class="i18n" data-i18n="How are you?">How are you?</span>

A special function call in goldstone.i18n will inspect the dom for i18n class tags, and use the data-i18n attribute for the translation key. This allows for a consistent string reference even after the text has been translated into a different language.