Building localized Flex Applications

Flex Built-in solution

To build localized application with flex adobe recommended the ResourceBundle API. The main problem with ResourceBundle API on Flex2 is the impossibility to switch bundle at runtime. So you will have to build one application for each language. In Flex3 this problem is solved with the new resourceManager that’s enables you to switch over pre-compiled Resource Bundle at runtime. Yet the compilation of each bundle can become harder and harder to maintain.

Using ResourceBundle for editorial text and short labels is difficult because:

  • The ResourceBundle are not handy for editorial users
  • The ResourceBundle need to be built
  • You can’t build an Administration application for editing localization labels because ResourceBundle are binary file.
  • Syntax to calling labels with ResourceBundle is a bit painful:
     <mx:Label text="{resourceManager.getString('myResources', 'GREETING')}" fontSize="48"/>

It’s why we create the globalization package as a complement of ressourceBundle.

The Globalization package

With the globalization package (org.servebox.toolbox.globalization), the AS Foundry offers the possibility to store all localized labels and texts into a single XML file, loaded on application initialization. All parts of localization can be handled by xml file. The localization file could be generated by any server solution (java / php / ruby etc…) or simply stand as a simple file on the web root.

The XML structure

<?xml version="1.0" encoding="utf-8"?>
<schema>
<languages>
<language name="FR"><![CDATA[Français]]></language>
<language name="EN"><![CDATA[English]]></language>
</languages>
<keys>
<!-- == Textes génériques == -->
 
<key id="forgotten_password">
<label language="FR"><![CDATA[Mot de passe oublié ?]]></label>
<label language="EN"><![CDATA[Password forgotten ?]]></label>
</key>
<key id="Search">
<label language="FR"><![CDATA[Recherche]]></label>
<label language="EN"><![CDATA[Search]]></label>
</key>
<key id="enter_mail">
<label language="FR"><![CDATA[Saisissez un e-mail (celui-ci servira de login)]]></label>
<label language="EN"><![CDATA[Type an e-mail (used as login)]]></label>
</key>

Load The XML file at startup

Using ASfoundry implies to have your own YourApplication which extends AbstractApplication. AbstractApplication has a reference on YourController class. On initialization process, YourController.initializeModels() will be run. You should run the retrieving process of the localization file in this method. GlobalizationDictionary is a singleton which had a method “load”.

YourController.as :

         /**
         * Initializes the application data models.
         */
        override public function initializeModels():void
        {
             // register application model
             ModelLocator.getInstance().registerModel( USER_MODEL, new UserModel() );
             ModelLocator.getInstance().registerModel( ADMIN_MODEL, new AdminModel() );
             // load the localization
             GlobalizationDictionary.getInstance().load( "resources/xml/localization.xml" );
        }

Remember, the localization.xml file is loaded at runtime as an external resource.

Accessing localized labels

Now we can use GlobalizationDictionaryReader instances to accessing to the localization data. Just instantiate GlobalizationDictionaryReader in your views or components and specify the language property. If the language property change, all labels will be updated.

e.g. :

   <!-- we assume that helper.language return 'fr' or 'en' -->
   <globalization:GlobalizationDictionaryReader id="reader" language="{helper.language}" />
        <mx:Form>
            <mx:FormItem label="{reader.labels.login}">
                <mx:TextInput/>
            </mx:FormItem>
            <mx:FormItem label="{reader.labels.password}">
                <mx:TextInput/>
            </mx:FormItem>
            <mx:FormItem label="">
                <mx:Button label="{reader.labels.ok_button}"/>
            </mx:FormItem>
        </mx:Form>

Previous Step

Next Step

Wednesday, December 17th, 2008 No Comments by Jeff Mathiot