Localizing an application using Resource Modules

If you need to localize an application and you have to support a lot of languages, the classic Resource Bundle approach could be very expensive in terms of swf file size, because it is compiled with all the defined languages.
With Resource Modules, Flex give you the possibility to create separate resource swf files (one for each language), that you can load programmatically, only when needed.
The starting point is the same of the Resource Bundle approach:
  • Create a locale folder inside the project root;

  • Create one folder for each language, named with the locale initials (e.g. en_US, it_IT, fr_FR, etc.);

  • Create a localization file inside each language folder (e.g. localizedContent.properties);

  • Fill each localizedContent file with your localization strings, classes, etc.


Example:

locale/en_US/localizedContent.properties
comboLabel=Select a language
welcome=Welcome to my application
helloLabel=Click to hail
helloMessage=Hello my friend!


locale/it_IT/localizedContent.properties
comboLabel=Seleziona una lingua
welcome=Benvenuto nella mia applicazione
helloLabel=Clicca per salutare
helloMessage=Ciao amico mio!


locale/fr_FR/localizedContent.properties
comboLabel=selectionnez une langue
welcome=bienvenue a ma application
helloLabel=cliqueter pour saluer
helloMessage=bonjour mon ami!

The Resource Modules have to contain not only your defined resources, but also the resources required by the Flex framework.
In order to identify which are the framework resources used by your application, you have to run the following command using the command line:


mxmlc -locale= -resource-bundle-list=resources.txt ResourceModules.mxml


The generated resources.txt file shows the list of framework resources that you have to include in the modules.

The file looks like this: bundles = collections containers controls core effects skins styles

Now you have to create the modules using mxmlc compiler (suppose to have english, italian and french languages):

mxmlc -locale=en_US -source-path=.,locale/{locale} -include-resource-bundles=collections,containers,controls,core,effects,skins,styles,localizedContent -output en_US_resx.swf

mxmlc -locale=it_IT -source-path=.,locale/{locale} -include-resource-bundles=collections,containers,controls,core,effects,skins,styles,localizedContent -output it_IT_resx.swf
mxmlc -locale=fr_FR -source-path=.,locale/{locale} -include-resource-bundles=collections,containers,controls,core,effects,skins,styles,localizedContent -output fr_FR_resx.swf

Three files are generated:

  • en_US_resx.swf;
  • it_IT_resx.swf;
  • fr_FR_resx.swf.

Those are the Resource Modules that we need to localize our application.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="onComplete()">
<mx:Script>
<![CDATA[
import mx.events.ResourceEvent;
import mx.controls.Alert;
import mx.collections.ArrayCollection;

// The current locale: the default is en_US
private var _currentLocale:String = "en_US";

protected function onComplete():void
{
// On creation complete set the locale with a default (en_US)
setupLocale(true);
}

private function setupLocale(forceLoad:Boolean=false):void
{
// Check if the resource is already loaded.
// The forceLoad flag is used to force the loading even if the resource has
// already been imported.
// During the initialization, the en_US loading has to be forced, because the
// english language is automatically included by Flex, but does not contain our
// resource definitions.
if(resourceManager.getLocales().indexOf(_currentLocale) == -1 || forceLoad)
{
// If the resource has not been loaded yet, or forceLoad=true, load the resource module
var dispatcher:IEventDispatcher = resourceManager.loadResourceModule(_currentLocale + "_resx.swf");
// Attach an event listener which has to be called when the module is completely loaded
dispatcher.addEventListener(ResourceEvent.COMPLETE, onResourceLoaded);
}
else
{
// If the resource has already been loaded, simply localize
onResourceLoaded(null);
}
}

/*
The following variables represent the parameters that have to be localized.
*/
[Bindable]
private var _comboLabelText:String;

[Bindable]
private var _welcomeText:String;

[Bindable]
private var _helloLabelText:String;

[Bindable]
private var _helloMessage:String;

private function onResourceLoaded(e:ResourceEvent):void
{
// Set the locale chain
resourceManager.localeChain = [_currentLocale];

// Modify the localization parameters
_comboLabelText = resourceManager.getString("localizedContent","comboLabel");
_welcomeText = resourceManager.getString("localizedContent","welcome");
_helloLabelText = resourceManager.getString("localizedContent","helloLabel");
_helloMessage = resourceManager.getString("localizedContent","helloMessage");


}

[Bindable]
private var _langs:ArrayCollection = new ArrayCollection(
[{name:"English", value:"en_US"},
{name:"Italiano", value:"it_IT"},
{name:"Francaise", value:"fr_FR"}]);

private function onHelloClick():void
{
// The message displayed depends on the selected language
Alert.show(_helloMessage);
}

private function onLangChange():void
{
// When the selected language of the combo box changes,
// the corresponding module is loaded
_currentLocale = langsCombo.selectedItem.value;
setupLocale();
}
]]>
</mx:Script>
<mx:VBox>
<mx:HBox>
<mx:Label text="{_comboLabelText}" />
<mx:ComboBox id="langsCombo" dataProvider="{_langs}" labelField="name" change="onLangChange()" />
</mx:HBox>
<mx:Label text="{_welcomeText}" />
<mx:Button id="helloBtn" label="{_helloLabelText}" click="onHelloClick()" />
</mx:VBox>
</mx:Application>

Comments on this post

Post a comment

Embed any code between [code] [/code] tags
captcha image   Reload