Introducing React ReExt – Sencha Ext JS Components in React! LEARN MORE

Internationalization & Localization with Sencha Ext JS

February 11, 2016 123 Views
Show

Guest Blog Post

Ext JS offers internationalization features out of the box, and the framework is easily extensible to cover additional requirements with a small amount of effort. Ext JS comes bundled with a localization package that supports over 40 languages ranging from Indonesian to Macedonian, and it’s easy to implement.

In this article, we’ll review solutions for handling some special circumstances and requirements that we’ve offered to our customers at Jnesis, but let’s first sum up what we know about internationalization.

The main focus is giving users the option to choose their preferred language for the application. This feature requires the application to be “translatable”, a feature that is often expressed with the words “i18n” or “internationalization.” “Translatable” meaning not only the possibility of translating into another language, but also considering all of the technical requirements attached to it.

Sencha provides a good internationalization and localization solution for the most common situations. It can also be extended, taking into consideration specific requirements of an enterprise environment. This makes it a powerful javascript web framework.

How can I Localize Ext JS Applications?

You will find details on the Sencha recommended way to localize your applications in the Sencha localization documentation. There are also some additional recommendations in community member Saki’s blog post. In the following post, we will address how to:

  • Write language files (singleton or override) directly in the application, so they can be integrated afterwards into the production build
  • Generate, via Sencha Cmd, as many production builds of the same application as there are languages set in the configuration
  • Reload the entire application each time the language is changed
  • Easily load additional resources before starting the application
  • Use different languages in different parts of the application

How to Localize Ext JS Applications

What is externalization of sources?

Enterprise developers view internationalization differently than the general developer because of their unique needs. Before choosing to adopt a framework and extend it, they must carefully assess their users’ actual needs. (See Sencha Day 2015 presentation by Vincent Munier, Technical Manager at Jnesis.)

Companies of a certain size generally come to the same conclusion: multilingual management is a concern that spans beyond the development framework. Multilingualism is a general concern for large organizations, because their business processes require different languages at different stages of product development and company evolution. In some cases where language requirements are changing regularly, translations should be done outside the application, mostly managed by third party software and loaded into the application via one or several web services.

The advantages of this approach are:

  • Changing the language doesn’t require the developer to rebuild the application – the change is applied instantly after reloading.
  • Translation doesn’t necessarily have to be done by the same people who write the code.

It could be argued that entrusting translation to people who do not know the code or how a JavaScript file is coded could pose some problems. However, it is perfectly conceivable to use a translation tier tool to translate content, one that can be used by non-programmers, and to load the data into the application.

As mentioned above, the official Ext JS solution can be found in its localization guide.

We will describe our approach which allows the tier tools to be implemented natively. It is important to introduce good practices for building internationalization into applications at the beginning of a project to avoid a painful refactoring phase.

Is there an Elegant Way?

Let’s first follow the Sencha localization guide and insights from Saki’s blog post: loading language data before the application main screen is built.

This solution is close to what was possible before Ext JS 5: adding dependencies to specific resources in the application’s “index.html” file.

Ext JS App Build

To achieve that, let’s first store the translations as variables of a “singleton” class, like this:

Ext.define('Jnesis.Labels', {
    singleton: true,
    button: 'My english button',
    title: 'My english title'
});

This will allow the translations to be accessed from anywhere in the application. How? As simply as typing Jnesis.Labels.button or Jnesis.Labels.title

The advantage of this approach compared to using “override” is that localized values will all be in one file, and easier to use, because each element is a variable, as explained above.

Once that is done, we simply have to override the default language file (« Jnesis.Labels ») with the translation in the selected language.

There are two options:

    1. Loading the data via web services, where the server JSON response would look like this:

 

{
    "button": "Mon Bouton",
    "title": "Mon titre"
}

We then would have to parse data and override our default localization singleton with those values:

Ext.define ('Jnesis.Application', {
    launch:  function () {
        Ext.Ajax.request({
            url: 'get-localization',
            params:{locale:'fr'},
            callback: function (options, success, response) {
                var data = Ext.decode(response.responseText, true);
                Ext.override(Jnesis.Labels, data);
                Ext.create('Jnesis.view.main.Main');
            }
        });
    }
});
    1. Loading overriding Ext JS classes:

 

Ext.define('Jnesis.locale.fr.Labels', {
    override: 'Jnesis.Labels',
    button: 'Mon Bouton',
    title: 'Mon titre'
});

Then using Ext.Loader.loadscript function to process it and loading our Main view when it’s done:

Ext.define ('Jnesis.Application', {
    launch: function () {
        var lang = 'fr',
            url = 'resources/locale/'+lang+'/Labels.js';
        Ext.Loader.loadScript({
            url: url,
            onLoad: function (options) {
                Ext.create('Jnesis.view.main.Main');
            }
        });
    }
});

We would then want to use the native inheritance mechanism to our advantage by defining a new property (“localized”, for example) in the base component, and generate the attribute to be translated. This attribute would be a simple JavaScript object with keys and values (remember the Jnesis.Labels.button and Jnesis.Labels.title from above).

Values can be updated only when the object is read, by defining the keys as strings:

Ext.define('Jnesis.view.main.Main', {
    extend: 'Ext.panel.Panel',
    localized: {
        title: 'Jnesis.Labels.title'
    },
    buttons: [{
        localized: {
            text: 'Jnesis.Labels.button'
        },
        handler: 'onClickButton'
    }]
});

Once that is done, we just have to override the “initComponent” method of the base class and evaluate the keys, so they can be used in any Ext JS component:

Ext.define('overrides.localized.Component', {
    override: 'Ext.Component',
    initComponent: function() {
        var me = this,
            localized = me.localized,
            value;
        if (Ext.isObject(localized)) {
            for (var prop in localized) {
                value = localized[prop];
                if (value) {
                    me[prop] = eval(value);
                }
            }
        }
        me.callParent(arguments);
    }
});

This solution works at any hierarchical level in the component’s declaration (container configuration or item configuration) in a transparent way.

What are some Additional Resources?

The latter solution works with both Ext JS 5 and 6 (Classic toolkit). You will find below examples of possible adaptations made by Jnesis in the past:

      • Deporting the loading functions and their associated processing in a specific class like “Ext.mixin.Mashup”. It ensures that every necessary file or JSON data from web services are loaded before the storage of the class to which the “mixin” is applied.
      • Ensuring compatibility with the Ext JS 6 Modern Toolkit. It has no “initComponent” function. Another option can be found in the “config” property and in the generation of the associated “apply” method.
      • Loading and interpreting the translation variables in a dynamic way without having to reload the entire application.

Please leave comments below, so we can share more information about these improvements. You can download the Jnesis extension from Sencha Market.

Show
Start building with Ext JS today

Build 10x web apps faster with 140+ pre-build components and tools.

Latest Content
Discover the Top 07 Architecture Patterns used in Modern Enterprise Software Development
Discover the Top 07 Architecture Patterns used in Modern Enterprise Software Development

Developing software without an architecture pattern may have been an option back then. However, that’s…

JavaScript Design Patterns: A Hands-On Guide with Real-world Examples
JavaScript Design Patterns: A Hands-On Guide with Real-world Examples

As a web developer, you know how popular JavaScript is in the web app development…

Virtual JS Days 2024のハイライト
Virtual JS Days 2024のハイライト

2024年2月20日~22日、第3回目となる「Virtual JavaScript Days」が開催されました。JavaScript の幅広いトピックを採り上げた数多くのセッションを実施。その内容は、Senchaの最新製品、ReExt、Rapid Ext JSまで多岐にわたり、JavaScriptの最新のサンプルも含まれます。 このカンファレンスでは多くのトピックをカバーしています。Senchaでセールスエンジニアを務めるMarc Gusmano氏は、注目すべきセッションを主催しました。Marc は Sencha の最新製品「ReExt」について、詳細なプレゼンテーションを実施。その機能とメリットを、参加者に理解してもらうべく詳細に説明しました。 カンファレンスは、Senchaのジェネラルマネージャを務めるStephen Strake氏によるキーノートでスタートしました。キーノートでは、会社の将来のビジョンについての洞察を共有しています。世界中から JavaScript 開発者、エンジニア、愛好家が集まるとてもエキサイティングなイベントとなりました。これは、JavaScript…

See More