FANDOM


I18n-js is a library for loading a script's messages, stored as JSON, ready for said script to use. Not only does it allow messages to be split out of the main code containing all the logic, it handles language fallbacks and basic parsing as well.

Usage

I18n page

To use I18n-js, you will need to set up your messages in the appropriate place and in the correct format. The message loader will expect your messages to be in a page such as MediaWiki:Custom-PAGENAME/i18n.json here on Dev Wiki, where PAGENAME should be the name of your script. the format of your messages should be as follows:

{
    "en": {
        "name": "value"
    },
    "pl": {
        "name": "wartość"
    }
}

Importing the script

Once you're all set up, simply import MediaWiki:I18n-js/code.js into your script. There are a few ways to achieve this, but they generally fall into one of two categories:

1. Import the script using importArticles or other import function that provides no indication of when the script has finished loading. If you use this method, you can listen for the dev.i18n event using mw.hook:

// register the hook before the import to avoid race conditions
mw.hook('dev.i18n').add(function (i18n) {
    // i18n is a shortcut to window.dev.i18n
});
 
importArticle({ type: 'script', article: 'u:dev:I18n-js/code.js' });

2. Import the script using a function that provides a callback, such as $.getScript. If you're using this method, you use the callback and access window.dev.i18n within:

$.getScript('/load.php?mode=articles&articles=u:dev:I18n-js/code.js&only=scripts')
    .done(function() {
        // access window.dev.i18n here
    });

Loading your messages

Now that the script is loaded, you're ready to load your messages. This is achieved using the loadMessages method of window.dev.i18n which returns an instance of i18n. This will also cache said instance in case you attempt to load the messages again for any reason:

// name is the PAGENAME part of http://dev.wikia.com/wiki/Custom-PAGENAME/i18n.json
i18n.loadMessages(name).done(function (i18n) {
    // use your i18n instance here
});

The loadMessages method also accepts an optional options object as the second argument, which may include the following properties:

  • cacheVersion: The minimum message cache version requested by the loading script. See §Message caching for details.
  • noCache: Never load the i18n messages from cache (this is not recommended for general use).

Message caching

Loaded messages will be cached in browser storage for up to two days after being loaded, in order to improve responsiveness on future page loads (as the script won't have to wait for messages to be loaded each time). However, this means that your script may use messages that are up to two days old. The cached messages also include a version number which defaults to 0 (zero).

If a new message is added in a script update, a cache refresh may be necessary to prevent missing messages before the two day cache expiry. To do this, you can use the cacheVersion option in your loadMessages call. If the cacheVersion option is used, it'll be compared to the cached version number, and if the cached version number is less than the requested version, the cache will be refreshed and the cached version number will be set to the requested version.

i18n usage

i18n controls access to your individual messages as well as the language it tries to translate them into. It defines the following 7 methods:

  • useLang(code): Set the default language to code, e.g. 'pt'. By default, the language will be the value of wgUserLanguage.
  • useContentLang(): Set the default language to the value of wgContentLanguage.
  • useUserLang(): Set the default language to the value of wgUserLanguage.
  • inLang(code): Set the language to code for the next message only.
  • inContentLang(): Set the language to the value of wgContentLanguage for the next message only.
  • inUserLang(): Set the language to the value of wgUserLanguage for the next message only.
  • msg(message, arg1, arg2, arg3, ...): Create a Message instance representing the message in the closest language to the default language possible with any arguments substituted in. See §Message usage for details on how to use this.

Message usage

Message represents a translated message in the closest language to the default language set in the i18n instance as possible. If a translation could not be found in the requested language, then it will try a fallback language instead, until it falls back to English. If the English translation could not be found, then it will contain the name of the message wrapped in < ... >, e.g. <MESSAGE>.

If your message uses arguments, these should be specified in the form $n where n is a integer greater than 0, e.g, 'Hello, $1, my name is $2'.

There are 3 methods available for outputting the message stored in the Message instance:

  • plain(): This outputs the message as is with no further processing.
  • escape(): This outputs the message with any HTML characters escaped.
  • parse(): This outputs the message with all basic wikitext links converted into HTML and some locale-specific magic words parsed. It also supports the inline tags <i>, <b>, <em>, <strong> and <span> and the attributes title, style and class. Note that disallowed tags will be removed along with their contents, disallowed attributes will be removed and url('...') in style attributes will cause the entire style attribute to be removed. The following wikitext syntax is supported:
    • [url text]
    • [[pagename]]
    • [[pagename|text]]
    • {{PLURAL:count|single|plural}} (more info)

Each Message instance also has 1 property:

  • exists: true if a translation was found for the message, else false.

If inLang, inContentLang or inUserLang are being used, you can also chain the message call:

// start with the user's language (let's say English)
i18n.msg('hello-world').plain(); // Hello World!
 
// output French for one message only
i18n.inLang('fr').msg('hello-world').plain(); // Bonjour le monde !
 
// and back to English again
i18n.msg('hello-world').plain(); // Hello World!

Editing your messages

JSON can be a bit tricky to edit, especially if you're unfamiliar with the syntax. To improve the editing experience, a dedicated editor can be found at Special:Blankpage/i18nedit.

Overriding messages

Sometimes, an end-user may wish to customise a set of messages according to their own preferences or even for a site-wide installation. This can be achieved using the following:

// in a user or site.js file
 
// initialise the global objects used without overwriting any already there
window.dev = window.dev || {};
window.dev.i18n = window.dev.i18n || {};
window.dev.i18n.overrides = window.dev.i18n.overrides || {};
window.dev.i18n.overrides['EXAMPLE'] = window.dev.i18n.overrides['EXAMPLE'] || {};
 
// customise the desired messages
window.dev.i18n.overrides['EXAMPLE']['some-message'] = 'My customised message';
window.dev.i18n.overrides['EXAMPLE']['another-message'] = 'Another customised message';

EXAMPLE is the name used by the message loader to identify where to load the message from. For example, for the name I18nEdit, the page would be u:dev:MediaWiki:Custom-I18nEdit/i18n.json. Therefore to customise the messages of I18nEdit, you would use the following:

window.dev = window.dev || {};
window.dev.i18n = window.dev.i18n || {};
window.dev.i18n.overrides = window.dev.i18n.overrides || {};
window.dev.i18n.overrides['I18nEdit'] = window.dev.i18n.overrides['I18nEdit'] || {};
 
window.dev.i18n.overrides['I18nEdit']['title'] = 'My new title';

To find the name of a message, the QQX language code trick can be used. For scripts using I18n-js, the text will be shown as (i18njs-Example-some-message), where Example is the name of the script and some-message is the name of the message. For example, the edit-language message used in I18nEdit would show (i18njs-I18nEdit-edit-language).

Change log

19 September 2018
  • Added message caching functionality.
28 August 2018
  • Removed support for inline comments in JSON pages.
16 August 2018
  • Fixed an XSS issue when parsing messages.
  • Added an exists property to Message instances.
  • Added support for the PLURAL magic word when parsing messages.
  • Added support for the qqx language code to show keys of used messages.
21 June 2018
  • Added support for temporary language changes on a per message basis.
01 June 2018
  • Added support for some inline tags and attributes when using Message.parse().
29 May 2018
  • Added message override support.
21 February 2017
  • Prevent the script loading multiples times and causing the cache to be lost.
16 February 2017
  • Switched to factory method instead of constructors.
  • Fixed argument handling to start at $1 instead of $0.
  • Fixed link parsing for absolute URLs.
15 February 2017
  • Improved fallback behaviour to mirror that of MediaWiki.
  • Added argument handling.
  • Added basic parsing functionality.
13 February 2017
  • Initial release.

See also

Start a Discussion Discussions about I18n-js