Home > Adobe Flex > Adobe Flex 3: Load localization resources at runtime using XML

Adobe Flex 3: Load localization resources at runtime using XML

October 23rd, 2009 Leave a comment Go to comments

In a previous post, I wrote an article describing some of the localization weaknesses in Flex 3.

->  Adobe Flex 3.x Localization / Internationalization (i18n) Weaknesses

I had mentioned the concept of loading resources at runtime via a XML formatted document. In this article I will discuss how I accomplished this and provide a working sample and source code.


A fully working example and the source code are provided at the bottom of this article.


The Flex method for creating resource bundles for localization compiling them directly into SWF files works well for many applications and is an efficient method for handling localization.  They even go as far as allowing you to load different localization bundle SWFs at runtime to reduce the size of the main application by only loading the resource files that you need.  However, this method is not ideal for certain scenarios such as if you are creating a distributable application and want to allow your customers to edit or create resource files.  It can also become annoying to have to recompile a SWF just to make a small change to a resource string.   So for these types of scenarios you may prefer a resource solution that can load a simple text (XML) file at runtime.   Fortunately Flex does provide a means of dynamically creating resource files programmatically.

I have created a XmlResourceLoader class that uses the URLLoader to load the necessary XML resource files at runtime and dynamically generate the resource bundles in the Flex ResourceManager.   Since you may want to include a number of different fallback languages the  XmlResourceLoader class accepts a chain Array on the load method.  This allows you to define a locale specific resource chain such as “en_GB”, “en“.  Using this chain, the XmlResourceLoader will load both the “en_GB.xml” resource file and the “en” resource file.

        /**
        *  this function will dynamically load the XML resource
        *  files via HTTP if they have not already been
        *  previously loaded into memory.
        */
        public function load(localeChain:Array):void


This function will skip locales in the chain that have already been loaded.  So if you allow users to change selected locales at runtime, then subsequent calls to the XmlResourceLoader load function will waste time and resources re-fetching the same content XML.


If you are interested in what specific files were loaded after the load method was invoked, you can access the ArrayCollection of loaded resource files using this method:

        /**
        *  returns a list of resource files in use
        *  for the loaded locale chain.
        */
        public function get resourceFiles():ArrayCollection


The XML resource files are simply formatted like this:

  1. <resources>
  2. <resourceBundle name="myResources">
  3. <resource name="myResourceOrigin" value="English Lanugage; Culture Neutral"/>
  4. <resource name="myLocalizedLabel" value="Hello World!" />
  5. <resource name="myLocalizedButton" value="Color"/>
  6. <resource name="myResourceFlagImage" value="assets/images/english-flag.png"/>
  7. </resourceBundle>
  8. </resources>


Each XML file may contain one or more resource bundles (<resourceBundle name=”myResources”>).  Each resource bundle section may contain one or more resource definitions (<resource name=”myLocalizedButton” value=”Color”/>).  Each resource definition contains two attributes: name and value.  The name attribute is the resource key name used to resolve the resource string and the value is the localized value string that is returned for the Flex ResourceManager when attempting to resolve a named resource.


Sample Application Links



Categories: Adobe Flex
  1. October 26th, 2009 at 12:23 | #1

    This is an awesome solution to this problem. I’ve never been satisfied with the traditional “compiled” resource bundle solution, especially when integrating with other technologies. I agree that the compiled solution is very fast, but it requires a recompilation each time there is a new language/locale added. I don’t find recompilation useful and feel it has haunted Flex for awhile now, especially if there is a need to localize at runtime.

    Thanks and great work!

  2. October 26th, 2009 at 18:02 | #2

    Glad you like it! I’m sure there is room for improvement, but this code should provide a nice start for the runtime loading of resources.

    Thanks for stopping by!
    -Robert

  3. Richard
    November 14th, 2009 at 10:04 | #3

    Reminds me of an alternate translation scheme from years ago in an MS-Access application.

    Only 1 other idea: when you are sitting looking at source code
    label=”{resourceManager.getString(‘myResources’, ‘myLocalizedButton’)}”

    It’d be nice to do an instant lookup from IDE to reassure yourself: “is this string what I think it is?”.

    Or, a capability to insert/update a special format trailing comment… with the actual text in the default language ??

    I am using FlashDevelop right now, that’s the thing about Flex is the variety of IDEs or source editors people use. But if it was an external executable, it could be used by most IDEs that can invoke a command line utility and capture output.

  4. November 14th, 2009 at 10:44 | #4

    Hi Richard,

    I agree and wish there were better tooling for the localization effort.
    Take a look at this post, I personally don’t like the idea of explicitly defining a resource manager string lookup every single place I need to perform localization, so I take this approach:
    http://www.savage7.com/index.php/2009/08/adobe-flex-3-how-to-create-localized-ui-component-control/

    Thanks
    -Robert

  5. Pascal
    March 18th, 2010 at 09:02 | #5

    Hey Richard,

    I have a question regarding the resourceManager.update();
    If you set the localechain it already executes the update event so this class does the update function twice and it dispatches the change event two times.

    Is there a reason for the resourceManager.update(); to execute in this class?

    thanks in advance,
    pascal

  6. April 9th, 2010 at 20:07 | #6

    @Pascal
    Hi Pascal,

    Thanks for pointing that out, I did not realize the update was happening automatically on the setting of the locale chain.

  1. No trackbacks yet.