developer

Internationalizing Your Application

Time Estimate: 15 minutes

Difficulty Level: Intermediate

Summary

This example shows how to use the i18n support built into Mojito that includes top-level defaults and the capability to override the default languages of countries.

The following topics will be covered:

Implementation Notes

Resources Bundles for Languages

Mojito uses the YUI 3 Internationalization utility to support internationalization. To use the YUI Internationalization utility in Mojito, you create resource bundles in JSON that specify the keys and values for the strings that need localizing.

Location of Resource Bundles

These resource bundles are JavaScript files that are placed in the lang directory of the mojit.

This code example has the following three resource bundles in lang directory of the i18n mojit:

/mojits/i18n/lang
            /i18n_en-US.js
            /i18n_en-AU.js
            /i18n_fr-FR.js

Naming Conventions

File Names

Resource bundle files use the following naming convention:

{mojit_name}_{BCP 47 tag}.js

YUI Module Name

The YUI module name that is registered in the resource bundle file with YUI.add must have the following syntax: 'lang/{mojit_name}_{BCP 47 Tag}.js'

For example, the YUI module name of the resource bundle for US English of the mojit i18n would be 'lang/i18n_en-US'.

Example

From the content of the i18n_en-US.js resource bundle below, you see that the add method specifies the module, the BCP 47 language tag, and the TITLE key with its value. The YUI Internationalization utility is included by adding the string 'intl' to the requires array. The YUI module name also

YUI.add("lang/i18n_en-US", function(Y, NAME) {
  Y.Intl.add(
    "i18n",  // associated mojit
    "en-US",    // BCP 47 language tag
    // key-value pairs for this module and language
    {
      TITLE: "Hello!",
    }
  );
}, "3.1.0", {requires: ['intl']});

Using the intl Addon

In the controller.server.js file below, the intl.lang and intl.formData methods rely on the YUI Internationalization utility to select the language and format of the title and date. The YUI Internationalization utility uses the Intl.lookupBestLang method to determine the best language based on an application’s request and a module’s language support. You also need to include the Intl addon by adding the string ‘mojito-intl-addon’ to the requires array.

YUI.add('i18n', function(Y, NAME) {/
  Y.namespace('mojito.controllers')[NAME] = {

    index: function(ac) {
      // Default.
      ac.done(
        {
          title: ac.intl.lang("TITLE"),
          today: ac.intl.formatDate(new Date())
        }
      );
    }
  };
 }, '0.0.1', { requires: ['mojito-intl-addon']});

Configuring a Mojit to Run on Client

When trying to deliver HTML pages with the language and date format preferred by the user, it’s best to rely on the user’s browser settings. YUI, when running on the client side, can detect the browser settings to select the default translation and date format. During server-side execution, however, the preferred language and date format is determined by the order of languages listed in the mojit controller.

Fortunately, Mojito lets you configure applications to run on either the server or client side. Because this code example illustrates how to localize your application, we want to configure Mojito to run the application on the client to improve the chances of serving content in the user’s preferred language and date format.

To configure Mojito to run on the client, you simply set the "deploy" property to true as seen in the application.json file below.

[
  {
    "settings": [ "master" ],
    "specs": {
      "frame" : {
        "type" : "HTMLFrameMojit",
          "config": {
          "deploy": true,
          "child" : {
            "type" : "i18n"
          }
        }
      }
    }
  }
]

Setting Up this Example

To set up and run locale_i18n:

  1. Create your application.

    $ mojito create app locale_i18n

  2. Change to the application directory.

  3. Create your mojit.

    $ mojito create mojit i18n

  4. To configure you application to have the mojit code run on the client, replace the code in application.json with the following:

    [
      {
        "settings": [ "master" ],
        "specs": {
          "frame" : {
            "type" : "HTMLFrameMojit",
            "config": {
              "deploy": true,
              "child" : {
                "type" : "i18n"
              }
            }
          }
        }
      }
    ]
    
  5. Update your app.js with the following to use Mojito’s middleware, configure routing and the port, and have your application listen for requests:

    'use strict';
    
    var debug = require('debug')('app'),
        express = require('express'),
        libmojito = require('mojito'),
        app;
    
        app = express();
        app.set('port', process.env.PORT || 8666);
        libmojito.extend(app);
    
        app.use(libmojito.middleware());
    
        app.get('/status', function (req, res) {
            res.send('200 OK');
        });
        app.get('/', libmojito.dispatch('frame.index'));
    
        app.listen(app.get('port'), function () {
            debug('Server listening on port ' + app.get('port') + ' ' +
            'in ' + app.get('env') + ' mode');
        });
        module.exports = app;
    
  6. Confirm that your package.json has the correct dependencies as show below. If not, update package.json.

    "dependencies": {
        "debug": "*",
         "mojito": "~0.9.0"
    },
    "devDependencies": {
        "mojito-cli": ">= 0.2.0"
    },
    
  7. From the application directory, install the application dependencies:

    $ npm install

  8. Change to mojits/i18n.

  9. Replace the code in controller.server.js with the following:

    YUI.add('i18n', function(Y, NAME) {
      Y.namespace('mojito.controllers')[NAME] = {
    
        index: function(ac) {
          // Default.
          ac.done(
            {
              title: ac.intl.lang("TITLE"),
              today: ac.intl.formatDate(new Date())
            }
          );
        }
      };
    }, '0.0.1', { requires: ['mojito-intl-addon']});
    
  10. To add the resource bundle for American English, create the file lang/i18n_en-US.js with the following:

    YUI.add("lang/i18n_en-US", function(Y, NAME) {
      Y.Intl.add(
        "i18n",  // associated mojit
        "en-US",    // BCP 47 language tag
        // key-value pairs for this module and language
        {
          TITLE: "Hello!"
        }
      );
    }, "3.1.0", {requires: ['intl']});
    
  11. To add the resource bundle for French, create the file lang/i18n_fr-FR.js with the following:

    YUI.add("lang/i18n_fr-FR", function(Y, NAME) {
      Y.Intl.add(
        "i18n",  // associated mojit
        "fr-FR",    // BCP 47 language tag
        // key-value pairs for this module and language
        {
          TITLE: "Tiens!"
        }
      );
    }, "3.1.0", {requires: ['intl']});
    
  12. To add the resource bundle for Australian English, create the file lang/i18n_en-AU.js with the following:

    YUI.add("lang/i18n_en-AU", function(Y, NAME) {
      Y.Intl.add(
        "i18n",  // associated mojit
        "en-AU",    // BCP 47 language tag
        // key-value pairs for this module and language
        {
          TITLE: "G'day!"
        }
      );
    }, "3.1.0", {requires: ['intl']});
    
  13. To modify the index template to show a localized message, replace the code in views/index.hb.html with the following:

    <div id=""class="mojit"> -- </div>
    
  14. From the application directory, run the server.

    $ node app.js

  15. To view your application in the default language used by your browser, go to the URL:

    http://localhost:8666

  16. Configure your browser to use French as the default language. To change the language preferences of Firefox or Chrome, see the Firefox instructions and Chrome instructions.

  17. Now go to your application URL and see the page display French.

  18. To force the page to display a specific language and date format, you can also use the query string parameter lang. The URL below uses the lang parameter to display the page in Australian English:

    http://localhost:8666?lang=en-AU