08/05/2013

Flex String internationalisation with Flexmojos


I wanted to support internationalisation on a pretty complex Flex project that was sharing some Components and Skins using Flex Libraries (swc files). I have spent a good amount of time searching for documentation and its just not there, the only examples I could find are the very simplest options you could possibly use and they are not even clear, so I'm going to try to write all the steps to get internationalisation working on your Flex app and compiling with Flexmojos here.

Flex Version: 4.6.b.23201 (I had to change to this from 4.6.0.23201 because I couldn't get this one from any online repository as easily as 4.6.b.23201, but they should behave the same way)
Maven repository: http://repository.sonatype.org/content/groups/flexgroup
Flexmojos version: 4.2-beta


This technique might also work with other versions, but I haven't tried.

Adding the properties files

First thing to note is where to add the properties files, I recommend to use the standard approach, which is adding a "locale" folder at the root of your project with the different language folders inside it. This applies both for a library and an application project:


As you can see, I am planning to support English, Spanish and Japanese.

Accessing the properties files from the code

Now, how do you access the properties files from the Flex application? I personally like resourceManager better, but there are different ways of doing it, you can read more about it here

A sample on my app would look like this:

 <s:Button id="registerBtn"  
           label="{resourceManager.getString('LoginComponentSkin','LoginComponentSkin.registerBtn_label')}"  
           height="30"  
           styleName="panel_text_button txtLinkBtn"  
           left="0" />  


Making Flexmojos compile language resource bundles

Configuration for the library project pom.xml

<plugin>
   <groupId>org.sonatype.flexmojos</groupId>
   <artifactId>flexmojos-maven-plugin</artifactId>

   <configuration>
      <localesSourcePath>${basedir}/locale/{locale}</localesSourcePath>

      <locales>
         <param>${flex.compiler.locale}</param>
      </locales>

      <localesRuntime>
         <locale>en_US</locale>
         <locale>es_ES</locale>
         <locale>ja_JP</locale>
      </localesRuntime>
   </configuration>
</plugin>


Note that the value of ${flex.compiler.locale} is:

<flex.compiler.locale>en_US,ja_JP,es_ES</flex.compiler.locale>

When you run mvn install on the library project it will produce different output files for each resource bundle that you include. The output should be something like this:



Configuration for the Application Project pom.xml

<configuration>
   <sourceFile>${basedir}/src/main/flex/MixAdminShell.mxml</sourceFile>

   <localesSourcePath>${basedir}/locale/{locale}</localesSourcePath>

   <locales>
       <param>${flex.compiler.locale}</param>
   </locales>

   <localesCompiled>
      <locale>en_US</locale>
      <locale>es_ES</locale>
      <locale>ja_JP</locale>
   </localesCompiled>
   ...
</configuration>
 
We also need to add dependencies to the resource bundles generated for the libraries on the dependencies section:

      <dependency>
         <groupId>com.investlab</groupId>
         <artifactId>flex-mix-components</artifactId>
         <version>${project.version}</version>
         <type>swc</type>
      </dependency>

      <dependency>
         <groupId>com.investlab</groupId>
         <artifactId>flex-mix-components</artifactId>
         <version>${project.version}</version>
         <type>rb.swc</type>
         <classifier>ja_JP</classifier>
      </dependency>

      <dependency>
         <groupId>com.investlab</groupId>
         <artifactId>flex-mix-components</artifactId>
         <version>${project.version}</version>
         <type>rb.swc</type>
         <classifier>en_US</classifier>
      </dependency>

      <dependency>
         <groupId>com.investlab</groupId>
         <artifactId>flex-mix-components</artifactId>
         <version>${project.version}</version>
         <type>rb.swc</type>
         <classifier>es_ES</classifier>
      </dependency>


MISSING TRANSLATIONS

Flex framework doesn't have all the libraries translated to all the languages, so when you compile you may find that some resource bundles from the framework are missing (in Spanish, for version 4.6.b.23201 the missing resource bundle libraries are flash-integration-4.6.b.23201-es_ES.rb.swc and  playerglobal-4.6.b.23201-es_ES.rb.swc). If you want to do a quick test on 4.6.b.23201 try adding Japanese only, all libraries are available for it.

Spanish versions available here:

How to do the needed translations

1- Download the English version of each file (I will do the example with one, but just apply the same to the rest of them):

Grab the English version from the framework:


Open it (do not decompress it! You can do this opening it with WinRAR on Windows or Springy on a Mac), the content will look like this:


2- You need to change the name of the folder "es_US" to your preferred language, in this case "es_ES"

3- In some cases "empty.properties" will contain strings in the associated language, you will need to translate them on that file to your preferred language

4- Open the file "catalog.xml" and change the reference to "en_US" for "es_ES" at the bottom:

 <?xml version="1.0" encoding ="utf-8"?>  
 <swc xmlns="http://www.adobe.com/flash/swccatalog/9">  
  <versions>  
   <swc version="1.2" />  
   <flex version="4.6.0" build="23201" minimumSupportedVersion="3.0.0" />  
  </versions>  
  <features>  
   <feature-script-deps />  
   <feature-files />  
  </features>  
  <libraries>  
   <library path="library.swf">  
    <script name="_e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855_flash_display_Sprite" mod="1320959596103" signatureChecksum="480278969" >  
     <def id="_e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855_flash_display_Sprite" />  
     <dep id="flash.display:Sprite" type="i" />  
     <dep id="AS3" type="n" />  
     <dep id="flash.system:Security" type="e" />  
    </script>  
    <digests>  
     <digest type="SHA-256" signed="false" value="8afed981420976a5478998fbde89d028e703063c306806a61d9d16b7d196a205"  />  
    </digests>  
   </library>  
  </libraries>  
  <files>  
   <file path="locale/en_US/empty.properties" mod="1303837923608" />  
  </files>  
 </swc>  

5- Now save your file, and you have to upload it to your Repository (in my case I use Artifactory), making sure that the properties of the deployed file match the english version's (DO NOT FORGET THE CLASSIFIER OPTION):

<dependency>
    <groupId>com.adobe.flex.framework</groupId>
    <artifactId>flash-integration</artifactId>
    <version>4.6.b.23201</version>
    <classifier>es_ES</classifier>
    <type>rb.swc</type>
</dependency>

If you run mvm clean install again it should pick up the new library and continue with the compilation further, probably until the next resource bundle is missing and you will have to repeat the translation process again for the new file until you have all the required bundles translated.

I hope it helps :)

4 comments:

  1. thanks you this is really useful!

    ReplyDelete
  2. Thank you! Glad you found it helpful :)

    ReplyDelete
  3. Thanks for such a helpful information. It really works. Appreciate your work. Keep it on.

    ReplyDelete
  4. Thanks for the support Sachin, I'm glad you found the information useful :)

    ReplyDelete