Tuesday, June 8, 2010

Localizing Flex Applications

In my attempt to localize my flex application, it quickly became evident how simple it is to do basic localization in flex. As soon as I tried to implement more complex features, I realized how complicated it can become (e.g. add special characters, support multiple locales, flex builder problems, etc). In the interest of sharing the wealth, I'll describe the steps I took, so I don't have to keep on repeating some of these in future development efforts. These steps are:

  • Trade-offs between @Resource and ResourceManager
  • Configuration of resource bundles following the flex convention. 
  • Adding it to the source path (not necessarily overlapping).
  • Flex Framework compilation (usage of copylocale)
  • Problems with FlexBuilder proper compilation of multiple 
  • Special characters within resource bundles (ISO-8859-1 vs UTF-8)


Understanding the Tradeoffs @Resource and ResourceManager
@Resource and ResourceManager and basically the two ways to retrieve localized messages. The choice of either of these depends on the design and requirements of your application. I would imagine that if I have to do a "quick" prototype, the @Resource component is the way to go (although one can argue the need of localization during early prototyping).  In constrast, the ResourceManager component provides a far more flexible way to configure the resolution of your bundles as well as the locale to be used to fetch all messages. One other caveat is that if you need to localize a .as file, then you are pretty much stucked with the ResourceManager object. Nothing bad, simply more configuration to add to your source code (with the ResourceBundle metadata tag). I have found that ResourceManager provides a far better approach to localization and will have to have a very good reason to use @Resource.

Configuring all resource bundles
All resource bundles (for those of you who are Java Developers) would be of  the form .properties. The flex convention is that it should be in a directory named after the locale name. This is different than traditional Java conventions where the locale is part of the bundle name. The compiler flags can then use the token {locale} anywhere to denote the locale directory of choice.

Dealing with the source path
In most configurations I've seen, there's a need to have the compiler flag:
-allow-source-path-overlap=true
This is not necessarily true. This should be done if the directory containing the folder with the locale exists in the same directory where the source code to be compiled resides. FlexBuilder (as well as FlexMojos) provides the ability to add additional source paths which will allow you to compile just fine.

Flex Framework localization
In case this is your first time localizing an application in your development environment, you will need to do an extra step to properly run your application locally. There is a nifty tool called copylocale which basically allows you to generate a locale for the flex framework in the language of your choice (as long as its supported by the tool). The syntax is something like:
copylocale en_US destination_locale_name
So, in order to prepare your flex environment to use Spanish (Spain), you would have to do:
copylocale en_US es_ES
Upon successful execution, you should see a new directory in the frameworks/locale directory with the name es_ES

Problems with Flex Builder
Everywhere in the documentation it suggested to do the following (including FlexBuilder)
-locale=en_US,es_ES
This didn't work for me in FlexBuilder. I tried the following:
-locale=en_US es_ES
(notice the white space instead of the comma between locale names) and it worked fine. Flexmojos had a different configuration.

Special Characters
Regarding special characters, my main problem was to ensure that all file encoding to be UTF-8 (the default is  ISO-8859-1). This is bad if you try to use the escape sequence characters in flex to add special characters. Once you configure file encoding in FlexBuilder (Preferences > General > Workspace), you are good to go. I copied and pasted the proper translation from Google translate. It worked very well (at least for me).

Hope this helps!

No comments: