Flex Localization – Changement de locale en dynamique avec ResourceManager
L'usage principal de la "localization" est de mettre à disposition de l'utilisateur plusieurs langues pour une seul et même application Flex et de laisser l'utilisateur changer cette langue (locale) à l'exécution. Vous pouvez compiler toutes ces langues possibles dans votre application et laisser ensuite choisir l'utilisateur parmi elles. Cette solution n'est pas très flexible car vous pourrez uniquement sélectionner les langues que vous avez ajouté à la compilation. Cette solution peut aussi amener à faire gonfler le poids de l'application Flex car tous les fichiers .properties et leur dépendances (images, vidéos...) doivent être compilées dans l'application.
Vous pouvez aussi compiler cet fichiers properties dans des fichiers SWF appelés Resource Modules. Ces Modules contiennent chacun ce qu'il faut pour un langage et pourront ensuite être chargés à l'exécution. L'avantage de cette approche est que le fichier SWF principal de l'application sera plus petit car les resources sont externalisées, mais cela demande aussi une requête supplémentaire pour chaque Resource Module que l'utilisateur charge.
On va d'abord voir comment cela se déroule quand on compile les fichiers de langue dans l'application.
Vous pouvez changer de "locale" (langue nationale) à l'exécution en changeant la valeur de la propriété "localeChain" du ResourceManager. Cette propriété prend un Array comme valeur. Le premier élément de cet Array est la langue courante (comme en_US, fr_FR ou es_ES).
Pour être capable de changer de locale à l'exécution sans utiliser les Resource Modules, on va compiler toutes les langues disponible dans l'application grâce à l'option "-locale". Cette option prend une liste de langue séparée par une virgule. Pour ajouter une autre langue comme le français (fr_FR), on va modifier l'option locale comme ceci:
-locale=en_US fr_FR
Une application Flex utilise la liste de locales de la propriété "localeChain" pour déterminer les priorités quand il va aller chercher les valeurs dans les Resource Bundles. Si une valeur n'existe pas dans la première locale de la liste, l'application Flex va aller chercher cette valeur dans la prochaine locale sur la liste et ainsi de suite.
Avant de compiler des locales dans votre application, vous devez générer les resources du framework pour cette locale. Vous pouvez le faire avec l'utilitaire copylocale:
Flex Localization - Ajouter de nouvelles langues (locale)
L'ordre des locales dans la ligne de commande peut être important. L'application prendra par défaut la première locale de la liste si vous ne spécifiez pas la propriété localeChain du ResourceManager quand l'application s'initialise.
L'exemple permet de sélectionner une nouvelle locale depuis une ComboBox Flex. Quand vous modifiez sa valeur, l'application met à jour la propriété localeChain. Les éléments spécifiques au langage de l'application (image, textes...) changeront donc directement:
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp()">
<mx:Script><![CDATA[
import mx.resources.ResourceBundle;
import mx.controls.Alert;
[Bindable]
private var locales:Array = [ "fr_FR","en_US" ];
private function initApp():void {
b1.setStyle("downSkin", resourceManager.getClass("RegistrationForm", "flag"));
// Initialize the ComboBox to the first locale in the locales Array.
localeComboBox.selectedIndex = locales.indexOf(resourceManager.localeChain[0]);
}
private function registrationComplete():void {
Alert.show(resourceManager.getString('RegistrationForm', 'thanks'));
}
private function comboChangeHandler():void {
// Set the localeChain to either the one-element Array
// [ "en_US" ] or the one-element Array [ "fr_FR" ].
resourceManager.localeChain = [ localeComboBox.selectedItem ];
// This style is not bound to the resource bundle, so it must be reset when
// the new locale is selected.
b1.setStyle("downSkin", resourceManager.getClass("RegistrationForm", "flag"));
}
]]></mx:Script>
<mx:Metadata>
[ResourceBundle("RegistrationForm")]
</mx:Metadata>
<mx:Image source="{resourceManager.getClass('RegistrationForm', 'flag')}"/>
<mx:ComboBox id="localeComboBox"
dataProvider="{locales}"
change="comboChangeHandler()"
/>
<mx:Form>
<mx:FormItem label="{resourceManager.getString('RegistrationForm','personname')}">
<mx:TextInput/>
</mx:FormItem>
<mx:FormItem label="{resourceManager.getString('RegistrationForm','street_address')}">
<mx:TextInput/>
</mx:FormItem>
<mx:FormItem label="{resourceManager.getString('RegistrationForm','city')}">
<mx:TextInput/>
</mx:FormItem>
<mx:FormItem label="{resourceManager.getString('RegistrationForm','state')}">
<mx:TextInput/>
</mx:FormItem>
<mx:FormItem label="{resourceManager.getString('RegistrationForm','zip')}">
<mx:TextInput/>
</mx:FormItem>
</mx:Form>
<mx:Button id="b1" label="{resourceManager.getString('RegistrationForm','submit_button')}" click="registrationComplete()"/>
</mx:Application>
Flex Source Code Download: Télécharger le code source complet de l'application
Si vous obtenez l'erreur "unable to open ‘C:\Program Files\Adobe\Flex Builder 3\sdks\3.2.0\frameworks\locale\fr_FR’", c'est que vous n'avez pas copiez le framework pour fr_FR. Pour cette procédure, suivez le tutorial sur copylocale et le framework Flex localized
Quand vous compilez votre application, vous devez ajouter les 2 locales à l'option locale comme ceci:
-locale=en_US fr_FR -allow-source-path-overlap=true -source-path=locale/{locale}
Puisque cette application utilise plusieurs langues, il vous faut faire un fichier par langue. Vous devriez avoir la structure suivante pour votre projet:
/src/MainApplication.mxml /src/locale/en_US/RegistrationForm.properties /src/locale/en_US/images/us-flag.gif /src/locale/fr_FR/RegistrationForm.properties /src/locale/fr_FR/images/fr-flag.gif
Les contenus de ces fichiers sont les suivants:
# /locale/en_US/RegistrationForm.properties
registration_title=Registration
submit_button=Submit Form
personname=Name
street_address=Street Address
city=City
state=State
zip=ZIP Code
thanks=Thank you for registering!
flag=Embed("images/us-flag.gif")
# locale/fr_FR/RegistrationForm.properties
registration_title=Inscription
submit_button=Valider le formulaire
personname=Nom
street_address=Rue
city=Ville
state=Etat
zip=Code Postal
thanks=Merci pour votre enregistrement
flag=Embed("images/fr-flag.gif")
Si vous ne faîtes pas un Binding de ces propriétés avec les valeurs de votre application, ces valeurs ne seront pas mises à jour quand la locale est modifiée.
Quand vous compilez une application avec plusieurs locales, la propriété "localeChain" du ResourceManager est initialisée à la valeur spécifiée par l'option -locale. Par exemple, si l'option locale est -locale=en_US fr_FR, l'application utilisera par défaut les ressources anglaises car en_US est listé en premier. Vous pouvez surcharger cette valeur initiale en spécifiant une valeur de localeChain dans un flashVars du template HTML.
Quand vous écrivez votre propre template HTML, vous pouvez passer des variables comme propriétés flashVars dans les tags <object> et <embed>. L'exemple suivant spécifie que la langue "fr_FR" est la première dans la localeChain:
<object id='mySwf'
classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'
codebase='http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab'
height='100%'
width='100%'>
<param name='src' value='BasicLocaleChain.swf'/>
<param name='flashVars' value='localeChain=fr_FR,en_US'/>
<embed name='mySwf'
src='FlashVarTest.swf'
pluginspage='http://www.adobe.com/go/getflashplayer'
height='100%'
width='100%'
flashVars='localeChain=fr_FR'
/>
>
Si vous utilisez les templates du SDK Flex, passez la propriété FlashVars à la méthode JavaScript AC_FL_RunContent() comme ceci:
AC_FL_RunContent(
"src", "BasicLocaleChain",
"flashVars", "localeChain=fr_FR,en_US",
"width", "500",
"height", "500",
"align", "middle",
"id", "BasicLocaleChain",
"name", "BasicLocaleChain",
"allowScriptAccess","sameDomain",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer"
);
Articles similaires
- Flex Localization – Chargement de Resource Modules à la volée
- Flex Localization – Formatter des dates, temps et unités suivant la locale
- Flex Localization – Utilisation des Resource Bundles avec le ResourceManager
- Flex Localization – ResourceManager et ses différentes méthodes (getString, getInt, getClass…)
- Flex Localization – Pré-chargement de Resource Modules (preload)
Aucun trackbacks pour l'instant






15 avril 2009
Chose intéressante quand on utilise la localisation est le localeChain. Comme on le voit, il s'agit d'un tableau.
Si on a un fichier pour en_US et un pour fr_FR, on peut faire
En faisant ceci, lorsque l'application cherche une resource fr_FR, si elle ne la trouve pas, elle ira chercher celle présente en en_US...
Assez peu d'intérêt en prod, mais très pratique en dev pour ne pas être obligé de tout traduire directement