ZPT-JS tutorial - I18n

Intro to i18n

Nowadays ZPT-JS has some i18n capabilities. How do they work? Let's see an example:

i18n.js
"use strict";

var zpt = require( 'zpt' );
var I18n = zpt.I18n;
var I18nBundle = zpt.I18nBundle;

/* I18n maps init */
var msg = {
    en : {},
    es : {}
};

/* English i18n messages */
msg.en[ '/CONF/' ] = {
    language: 'en',
    locale: 'en-US'
};
msg.en[ 'Hello world!' ] = 'Hello world!';
msg.en[ 'Results msg' ] = '{GENDER, select, male{He} female{She} other{They} }' +
    ' found ' +
    '{RES, plural, =0{no results} one{1 result} other{# results} }';

/* Spanish i18n messages */
msg.es[ '/CONF/' ] = {
    language: 'es',
    locale: 'es-ES'
};
msg.es[ 'Hello world!' ] = '¡Hola mundo!';
msg.es[ 'Results msg' ] = '{ GENDER, select, male{Él} female{Ella} other{Ellos} }' +
    ' ' +
    '{ RES, plural, =0{no } other{} }' +
    '{ GENDER, select, male{ha} female{ha} other{han} }' +
    ' encontrado ' +
    '{ RES, plural, =0{ningún resultado} one{un único resultado} other{# resultados} }';

// Create I18n and i18nBundle instances
var i18nES = new I18n( 'es', msg[ 'es' ] );
var i18nEN = new I18n( 'en', msg[ 'en' ] );
var i18nBundle = new I18nBundle( i18nES, i18nEN );

// Init dictionary
var dictionary = {
    'i18nBundle': i18nBundle
};

// Parse template
zpt.run({
    root: document.body,
    dictionary: dictionary
});
                
i18n.html
<!DOCTYPE html>
<html lang="es">
    <head>
        <meta charset="utf-8">
        <title>Some I18n examples</title>

        <script src="i18n.js"></script>
    </head>
    <body>
        <h1>Some I18n expressions</h1>
        <ol data-language="'en'" data-domain="i18nBundle">
            <li>
               ¡Hola mundo! = 
               <span data-content="tr: 'Hello world!'">Must be ¡Hola mundo!</span>
            </li>
            <li>
               Él ha encontrado 10 resultados = 
                <span data-content="tr: 'Results msg' ( GENDER 'male'; RES 10 )">Must be 'Él ha encontrado 10 resultados'</span>
            </li>
        </ol>
    </body>
</html>
                

Some remarks about this:

Some examples

Some examples of i18n tags in action:

Some examples of valid data-domain attributes:

Working with domains

In the previous example the domain was a simple I18nBundle instance. This forces to use big maps with all the messages of one language. This can be awful if the amount of messages is big. data-domain tag supports also a list of I18nBundle instances, so the messages will be searched in the same order.

Therefore, data-domain="i18nBundle1 i18nBundle2" allows to organise your i18n messages in 2 maps. The first one can contain general messages and the second one more particular messages (for example).

data-domain also supports nested definitions:

<div data-domain="i18nBundle1">
   <span data-content="tr: 'Hello world!'">
        ¡Hola mundo!
   </span>
   <span data-domain="i18nBundle2" data-content="tr: 'Hello world!'">
        ¡¡¡Hola mundo 2!!!
   </span>
</div> 
                

The first data-content will search only in i18nBundle1. The second one will search first in i18nBundle2 and if it is not found will search in i18nBundle1.

Loading messages from JSON files

ZPT-JS makes it easy loading i18n messages from JSON files:

zpt.run({
    command: 'preload',
    root: document.body,
    dictionary: dictionary,
    i18n: {
        urlPrefix: './i18n/',
        files: {
            'es': [ 'es1.json', 'es2.json' ],
            'en': [ 'en1.json', 'en2.json' ]
        }
    },
    callback: function(){

        // Add I18nBundle instances to dictionary
        dictionary.i18nBundle1 = new I18nBundle( dictionary.i18nES1, dictionary.i18nEN1 );
        dictionary.i18nBundle2 = new I18nBundle( dictionary.i18nES2, dictionary.i18nEN2 );

        // Run ZPT
        zpt.run();
    }
});
                

ZPT will add to dictionary these vars:

The order in arrays is inverted: first the last files, then the first.

The bundles (i18nBundle1 and i18nBundle2) are not required, add to the dictionary if you need them.

Numbers

ZPT-JS uses Intl as i18n API for numbers. Let's see some examples:

Take a look on NumberFormat options to see all available options.

Currencies

ZPT-JS uses Intl as i18n API for currencies. Let's see some examples:

Options are the same as numbers (NumberFormat options) plus some specific options of currencies.

Dates and times

ZPT-JS uses Intl as i18n API for date and times. Let's see some examples:

Take a look on DateTimeFormat options to see all available options.