Les stratégies de localisation d'une application Flex Adobe eSeminar - 27/06/08 David Deraedt Centre Regart.net
Introduction <ul><li>Comment adapter une application Flex à différents langages, régions et cultures ? NB: Ici, on ne parl...
Introduction <ul><li>Il ne s'agit pas de que traduire du texte ! - Système de mesures (poids, taille, volume, surface, ......
Introduction <ul><li>Concernant le texte, au delà de la traduction, il y a d'autres enjeux : - Encodage - Alphabets - Sens...
Introduction <ul><li>Nouvelle distinction entre deux types de données à adapter : </li></ul><ul><ul><li>Données &quot;méti...
Données métiers  <ul><li>Comme tout ce qui concerne la partie métier = côté serveur. Exemple: Application qui traite de li...
Données de l'interface <ul><li>Plusieurs cas de figure : </li></ul><ul><ul><li>i18n statique : on compile pour une ou plus...
Données de l'interface <ul><li>  </li></ul>
Données de l'interface <ul><li>Du point de vue de l'utilisateur, 2 cas de figure : </li></ul><ul><ul><li>La langue est dét...
Données de l'interface <ul><li>Parfois, la langue désirée est passée en paramètre dans l'URL  http://www.website.com/page....
Quelles stratégies ? <ul><li>Comment implémenter l'i18n de notre application? </li></ul><ul><ul><li>On utilise le mécanism...
Les Resource Bundles <ul><li>Ce sont des fichiers &quot;.properties&quot; compilés : </li></ul><ul><ul><li>Simple fichiers...
Les Resource Bundles <ul><li>Syntaxe </li></ul><ul><ul><li>Couple Clef / valeur séparé par &quot;=&quot;, &quot;:&quot; ou...
Les Resource Bundles <ul><li>A retenir : </li></ul><ul><ul><li>On peut les utiliser pour autre chose que de la L10n (ex co...
Les Resource Bundles <ul><li>On va soit les compiler  </li></ul><ul><ul><li>dans l'application (i18n statique)  </li></ul>...
Framework Resource Bundles <ul><li>flex_builder_install/sdks/3.0.0/frameworks/locale/en_US/ => fichiers SWC Par défaut, il...
Framework Resource Bundles <ul><li>Pour ajouter une langue : utilitaire &quot;copylocale&quot;  flex_builder_install/sdks/...
Framework Resource Bundles <ul><li>Pour aller vite, inutile de devoir tout traduire :  avoir un répertoire du nom de la la...
Application Resource Bundles <ul><li>Convention : placer fichiers .properties dans répertoire : src/locale/[langue]_[regio...
Compiler les Bundles avec l'application <ul><li>C'est la méthode d'i18n statique : 1. Ajouter un chemin de compilation ver...
Compiler les Bundles avec l'application <ul><li>A noter : </li></ul><ul><ul><li>Pour se débarrasser du warning, on peut aj...
Compiler les Bundles séparément <ul><li>Problèmes d'une i18n &quot;statique&quot; (avec l'application) : </li></ul><ul><ul...
Compiler les Bundles séparément <ul><li>Tous les fichiers properties d'une langue sont compilés en un seul SWF. Pour compi...
Compiler les Bundles séparément <ul><li>Pour connaître les fichiers à compiler, on utilise un paramètre à la compilation d...
Compiler les Bundles séparément <ul><li>Pour charger un bundle : ResourceManager.loadResourceModule(rb.swf, true); Le 2ème...
Utiliser les Resource Bundles <ul><li>Comment utiliser les données dans notre application? En MXML, 2 solutions : syntaxe ...
Utiliser les Resource Bundles <ul><li>En AS3 : Metadata ResourceBundle devant la classe : [ResourceBundle(&quot;MyBundle&q...
Utiliser les Resource Bundles <ul><li>Mais tous les UIComponents ont une propriété  resourceManager  vers ce Singleton : E...
Changer de langue à l'exécution <ul><li>On utilise la propriété  localeChain  du  resourceManager private function changeL...
Charger d'autres types de données <ul><li>Charger autre chose que des chaînes : resourceManager.getNumber(&quot;myResource...
Charger d'autres types de données <ul><li>Par exemple, pour une image (imaginer un drapeau), on utilisera : resourceManage...
Stratégies alternatives <ul><li>On peut vouloir stocker ces données côté serveur d'application et/ou BDD : </li></ul><ul><...
Stratégies alternatives <ul><li>Comment procéder ? Deux solutions : </li></ul><ul><ul><li>Créer un mécanisme de toutes piè...
Stratégies alternatives <ul><li>package com. dehats . localize {     import  flash. events . IEventDispatcher ;       [ Ev...
Stratégies alternatives <ul><li><mx:Panel  title= &quot;{loc.getString('prodTitle')}&quot;   xmlns:mx= &quot;http://www.ad...
Stratégies alternatives <ul><li>S'appuyer sur les resources Bundles de Flex : 2 étapes 1. Créer sa propre classe ResourceB...
Stratégies alternatives <ul><li>2. L'ajouter au resourceManager var moreResources: MyResourceBundle =  new MyResourceBundl...
Le cas d'une application AIR <ul><li>Pas d'intéret particulier à charger dynamiquement les bundles : on va les compiler st...
Conclusion <ul><ul><li>Depuis Flex3, l'utilisation des RB côté application est satisfaisant : pas besoin de réinventer la ...
Questions / réponses <ul><li>David Deraedt - Flex My Day http://www.dehats.com Centre de formation Regart.net http://www.r...
Prochain SlideShare
Chargement dans…5
×

Les stratégies de localisation d'une application Flex

2 193 vues

Publié le

eSeminar for Adobe France, June 2008. (French)

Publié dans : Technologie, Business
0 commentaire
0 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Aucun téléchargement
Vues
Nombre de vues
2 193
Sur SlideShare
0
Issues des intégrations
0
Intégrations
17
Actions
Partages
0
Téléchargements
28
Commentaires
0
J’aime
0
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Les stratégies de localisation d'une application Flex

  1. 1. Les stratégies de localisation d'une application Flex Adobe eSeminar - 27/06/08 David Deraedt Centre Regart.net
  2. 2. Introduction <ul><li>Comment adapter une application Flex à différents langages, régions et cultures ? NB: Ici, on ne parlera pas de la traduction du code source Distinction localisation / internationalisation </li></ul><ul><ul><li>Internationalisation = i18n (Internationalization) = partie logicielle </li></ul></ul><ul><ul><li>Localisation = régionalisation = L10n (localization) = traduction / adaptation </li></ul></ul><ul><li>(Globalization = g11n = internationalisation + régionalisation) </li></ul>
  3. 3. Introduction <ul><li>Il ne s'agit pas de que traduire du texte ! - Système de mesures (poids, taille, volume, surface, ...) - Premier jour de la semaine - Fuseaux horaires - Formatage pour les dates - Devise (caractère et placement devant ou derrière la somme) - Images (drapeau) et couleurs - Points encore plus spécifiques => programmation - etc... </li></ul>
  4. 4. Introduction <ul><li>Concernant le texte, au delà de la traduction, il y a d'autres enjeux : - Encodage - Alphabets - Sens d'écriture (gauche-droite, vertical) - Différences d'orthographes selon les régions => Grande complexité si on veut aller loin </li></ul>
  5. 5. Introduction <ul><li>Nouvelle distinction entre deux types de données à adapter : </li></ul><ul><ul><li>Données &quot;métier&quot; </li></ul></ul><ul><ul><li>Données d'interface (titres, boîtes de dialogue, boutons, icônes, ...) </li></ul></ul>
  6. 6. Données métiers <ul><li>Comme tout ce qui concerne la partie métier = côté serveur. Exemple: Application qui traite de livres : les titres et résumé des différents livres dans différentes langues vont être stockés en base, et accédés côté serveur. Plusieurs stratégies possibles : </li></ul><ul><ul><li>Variable de session qui stocke la langue grâce à une méthode : exemple &quot;setLanguage(pLg);&quot; </li></ul></ul><ul><ul><li>Paramètre pour chaque méthode du service : exemple &quot;getBooks (pLg) ;&quot; </li></ul></ul><ul><ul><li>Objets transmis (VOs/ DTOs) contiennent toutes les traductions </li></ul></ul>
  7. 7. Données de l'interface <ul><li>Plusieurs cas de figure : </li></ul><ul><ul><li>i18n statique : on compile pour une ou plusieurs langues (paramètre de compilation) </li></ul></ul><ul><ul><li>i18n dynamique : les fichiers de localisation sont chargés dynamiquement </li></ul></ul><ul><li>Dans la majorité des cas, les données de traductions sont chargées dynamiquement : </li></ul><ul><ul><li>Moins lourd (on ne charge que ce dont on a besoin) </li></ul></ul><ul><ul><li>Plus souple : on peut changer les données sans avoir à recompiler toute l'application. </li></ul></ul>
  8. 8. Données de l'interface <ul><li>  </li></ul>
  9. 9. Données de l'interface <ul><li>Du point de vue de l'utilisateur, 2 cas de figure : </li></ul><ul><ul><li>La langue est déterminée au lancement et définitive </li></ul></ul><ul><li>   => Nécessité de recharger l'application (page web) pour changer de langue. </li></ul><ul><ul><li>La langue peut être modifiée à l'exécution (ex: combobox) </li></ul></ul><ul><li>   => Plus souple, mais peut être complexe car: </li></ul><ul><ul><li>Il va falloir tout &quot;databinder&quot; </li></ul></ul><ul><ul><li>Il va falloir aussi mettre à jour toutes les données métiers (compliqué si l'objet ne contient pas toutes les traductions) </li></ul></ul><ul><ul><li>Pas indispensable </li></ul></ul>
  10. 10. Données de l'interface <ul><li>Parfois, la langue désirée est passée en paramètre dans l'URL http://www.website.com/page.html?lg=&quot;en_US&quot; http://www.website.com/page.html#lg=&quot;en_US&quot; Pour récupérer cette variable : </li></ul><ul><ul><li>Flashvars </li></ul></ul><ul><li>var lg:String = application.parameters.lg ; </li></ul><ul><ul><li>BrowserManager </li></ul></ul><ul><li>var params:Object =  URLUtil.stringToObject(bm.fragment); var lg:String =params.lg; </li></ul>
  11. 11. Quelles stratégies ? <ul><li>Comment implémenter l'i18n de notre application? </li></ul><ul><ul><li>On utilise le mécanisme prévu par Adobe : Resource Bundles </li></ul></ul><ul><ul><li>On crée son propre mécanisme </li></ul></ul>
  12. 12. Les Resource Bundles <ul><li>Ce sont des fichiers &quot;.properties&quot; compilés : </li></ul><ul><ul><li>Simple fichiers textes </li></ul></ul><ul><ul><li>Format UTF8 </li></ul></ul><ul><ul><li>Couple Clef / valeur </li></ul></ul><ul><li>#locale/en_US/app.properties message=Hello, world! message-size=30 #locale/es_MX/app.properties message=¡Hola, mundo! message-size=40 </li></ul>
  13. 13. Les Resource Bundles <ul><li>Syntaxe </li></ul><ul><ul><li>Couple Clef / valeur séparé par &quot;=&quot;, &quot;:&quot; ou espace </li></ul></ul><ul><ul><li>Commentaires commencent par # ou ! </li></ul></ul><ul><ul><li>Si plus d'une ligne, on utilise le caractère backslash &quot;&quot; à la fin de la ligne précédente </li></ul></ul><ul><li>#locale/en_US/app.properties message=Hello, world! message-size=30 #locale/es_MX/app.properties message=¡Hola, mundo! message-size=40 </li></ul>
  14. 14. Les Resource Bundles <ul><li>A retenir : </li></ul><ul><ul><li>On peut les utiliser pour autre chose que de la L10n (ex config). Pas forcément conseillé. </li></ul></ul><ul><ul><li>Doivent être compilés par Flex (transformés en classe AS3 qui étendent ResourceBundle à la compilation) </li></ul></ul><ul><li>=> Pas très souple si on a pas de système d'intégration continue ! </li></ul>
  15. 15. Les Resource Bundles <ul><li>On va soit les compiler </li></ul><ul><ul><li>dans l'application (i18n statique) </li></ul></ul><ul><ul><li>séparément (i18n dynamique) </li></ul></ul><ul><li>Distinction deux familles de domaines de L10n : </li></ul><ul><ul><li>Framework Flex </li></ul></ul><ul><ul><li>Application elle-même </li></ul></ul><ul><li>    Attention : L'une ne va pas sans l'autre : si on ajoute une langue pour notre application, le framework doit être traduit dans cette langue ! </li></ul>
  16. 16. Framework Resource Bundles <ul><li>flex_builder_install/sdks/3.0.0/frameworks/locale/en_US/ => fichiers SWC Par défaut, il existe 2 langues : anglais US et japonais (Cf paramètres de compil par défaut du projet) Rappel syntaxe : [langue]_[region] : exemple en_US Les fichiers properties correspondants se trouvent dans : flex_builder_install/sdks/3.0.0/frameworks/projects/framework/bundles/en_US/src </li></ul>
  17. 17. Framework Resource Bundles <ul><li>Pour ajouter une langue : utilitaire &quot;copylocale&quot; flex_builder_install/sdks/3.0.0/bin Utilisation : copylocale en_US fr_FR Certains ont déjà fait le travail pour nous ! </li></ul><ul><ul><li>Adobe : http://opensource.adobe.com/wiki/display/flexsdk/Submitting+a+Patch </li></ul></ul><ul><ul><li>Projet BabelFlex (Tontons Flexeurs) : http://ttfx.org/Tontons_Flexeurs/BabelFlex.html </li></ul></ul><ul><li>Problème : les fichiers de datavisualisation ne sont pas traduits, pour eux c'est plus compliqué. cf http://philflash.inway.fr/flex/copylocale/index.html </li></ul>
  18. 18. Framework Resource Bundles <ul><li>Pour aller vite, inutile de devoir tout traduire : avoir un répertoire du nom de la langue qui nous intéresse, avec les bons SWC suffit ! On peut donc maintenant localiser notre application... </li></ul>
  19. 19. Application Resource Bundles <ul><li>Convention : placer fichiers .properties dans répertoire : src/locale/[langue]_[region]/fichier.properties On en créera un par &quot;domaine de traduction&quot; et par langue. Exemple :     src/locale/fr_FR/trads.properties         src/locale/en_US/trads.properties     src/locale/es_ES/trads.properties On peut aussi créer des projets de bibliothèques pour créer des SWC de Resource Bundles. </li></ul>
  20. 20. Compiler les Bundles avec l'application <ul><li>C'est la méthode d'i18n statique : 1. Ajouter un chemin de compilation vers le bundle Properties -> AS Build Path -> Source Path -> New Folder -> src/locale/{locale} 2. Changer le paramètre de langue de compilation : Properties -> Compiler -> -locale=[langue]_[region] ... ou dans flex-config.xml :     <locale>         <locale-element>en_US</locale-element>         <locale-element>es_ES</locale-element>     </locale> </li></ul>
  21. 21. Compiler les Bundles avec l'application <ul><li>A noter : </li></ul><ul><ul><li>Pour se débarrasser du warning, on peut ajouter un paramètre: -allow-source-path-overlap=true </li></ul></ul><ul><ul><li>On ajouter plusieurs langues à la suite : locale=en_US,  locale=fr_FR pour en compiler plusieurs à la fois. </li></ul></ul><ul><ul><li>Par défaut, c'est la première qui sera utilisée, ou celle précisée par le flashvars : localeChain=es_ES </li></ul></ul>
  22. 22. Compiler les Bundles séparément <ul><li>Problèmes d'une i18n &quot;statique&quot; (avec l'application) : </li></ul><ul><ul><li>Alourdit la taille de l'application </li></ul></ul><ul><ul><li>Impossible d'ajouter ou modifier les fichiers properties sans recompiler toute l'application </li></ul></ul><ul><li>Depuis Flex 3, il est possible de charger ces fichiers dynamiquement, une fois compilés (cf StyleManager et feuilles de style CSS). </li></ul>
  23. 23. Compiler les Bundles séparément <ul><li>Tous les fichiers properties d'une langue sont compilés en un seul SWF. Pour compiler les fichiers, on utilise une ligne de commande : mxmlc -locale=fr_FR -source-path=locale/{locale} -include-resource-bundles=MonFichier, collections,containers,controls,core,effects,skins,styles -output fr_FR_ResourceModule.swf </li></ul>
  24. 24. Compiler les Bundles séparément <ul><li>Pour connaître les fichiers à compiler, on utilise un paramètre à la compilation d'une application : mxmlc -locale=       -resource-bundle-list=leFichier.txt MonApp.mxml La liste des bundles nécessaires est alors écrite dans leFichier.txt Note : Sous OSX, il faut donner un chemin absolu ! </li></ul>
  25. 25. Compiler les Bundles séparément <ul><li>Pour charger un bundle : ResourceManager.loadResourceModule(rb.swf, true); Le 2ème paramètre précise si l'application doit être mise à jour automatiquement. Pour précharger les resource modules, on a une flashvars : <param name='flashVars' value='resourceModuleURLs=es_ES_ResourceModule.swf &localeChain=es_ES'/> </li></ul>
  26. 26. Utiliser les Resource Bundles <ul><li>Comment utiliser les données dans notre application? En MXML, 2 solutions : syntaxe &quot;@&quot; et AS3. <mx:Label x=&quot;10&quot; y=&quot;10&quot; text=&quot;@Resource(key='zip', bundle='RegistrationForm')&quot;/> Le paramètre &quot;bundle&quot; peut être facultatif si le fichier properties a le même nom que la classe (déconseillé). Limite : pas de DataBinding => on préférera utiliser la méthode par AS. </li></ul>
  27. 27. Utiliser les Resource Bundles <ul><li>En AS3 : Metadata ResourceBundle devant la classe : [ResourceBundle(&quot;MyBundle&quot;)] public class MyClass {} ... puis, dans le code : var text:String = ResourceManager.getInstance().getString( 'RegistrationForm','personname') ; </li></ul>
  28. 28. Utiliser les Resource Bundles <ul><li>Mais tous les UIComponents ont une propriété resourceManager vers ce Singleton : En MXML : DataBinding => syntaxe AS3 : <mx:Metadata>   [ResourceBundle(&quot;RegistrationForm&quot;)] </mx:Metadata> ... et ensuite : <mx:Label x=&quot;10&quot; y=&quot;65&quot; text=&quot;{resourceManager.getString('RegistrationForm', 'personname')}&quot;/> </li></ul>
  29. 29. Changer de langue à l'exécution <ul><li>On utilise la propriété localeChain du resourceManager private function changeLanguage(pLg:String):void {     resourceManager.localeChain=[pLg]; } Tableau (Array) car on peut passer plusieurs langues simultanément (cascade): si un élément n'est pas dans la première, on va le chercher dans la deuxième, etc... </li></ul>
  30. 30. Charger d'autres types de données <ul><li>Charger autre chose que des chaînes : resourceManager.getNumber(&quot;myResources&quot;, &quot;PRICE&quot;); resourceManager.getInt(&quot;myResources&quot;, &quot;AGE&quot;); resourceManager.getUint(&quot;myResources&quot;, &quot;COLOR&quot;); resourceManager.getBoolean(&quot;myResources&quot;, &quot;SENIOR&quot;); Il existe aussi getClass(), getString(), getObject(), et getStringArray() . </li></ul>
  31. 31. Charger d'autres types de données <ul><li>Par exemple, pour une image (imaginer un drapeau), on utilisera : resourceManager.getClass(&quot;flag&quot;); Dans le resourceBundle, on aurait : flag=Embed(&quot;images/flag_fr.gif&quot;) Pour une classe, on utilise la directive ClassReference : SORTER=ClassReference(&quot;sortingClasses.en_US.Sorter&quot;) </li></ul>
  32. 32. Stratégies alternatives <ul><li>On peut vouloir stocker ces données côté serveur d'application et/ou BDD : </li></ul><ul><ul><li>Le serveur a un service spécial de traduction en plus des données métiers </li></ul></ul><ul><ul><li>Rarement utilisé, mauvais mélange des genre, pas forcément utile </li></ul></ul><ul><li>On préférera le format texte, généralement, en XML. Avantages : </li></ul><ul><ul><li>On peut s'appuyer sur des standards de traduction, comme le XLIFF (OASIS) </li></ul></ul><ul><ul><li>Pas besoin de compiler les ressources </li></ul></ul>
  33. 33. Stratégies alternatives <ul><li>Comment procéder ? Deux solutions : </li></ul><ul><ul><li>Créer un mécanisme de toutes pièces </li></ul></ul><ul><ul><li>S'appuyer sur les resourceBundles/ ResourceManager </li></ul></ul>
  34. 34. Stratégies alternatives <ul><li>package com. dehats . localize {     import flash. events . IEventDispatcher ;       [ Event ( name = &quot;change&quot; )]     public interface ILocalizer extends IEventDispatcher {         function get language () : String ;         function set language ( pLang: String ) : void ;         function get langXML () : XML         function set langXML ( pXML: XML ) : void         [ Bindable ( &quot;change&quot; )]         function getString ( pKey: String ) : String ;     } } </li></ul>
  35. 35. Stratégies alternatives <ul><li><mx:Panel title= &quot;{loc.getString('prodTitle')}&quot; xmlns:mx= &quot;http://www.adobe.com/2006/mxml&quot; layout= &quot;absolute&quot; width = &quot;400&quot; height = &quot;300&quot; > <mx:Script> <! [ CDATA [ import com. dehats . localize . * ; [ Bindable ] public var loc:ILocalizer ; ]] > </mx:Script> <mx: Button  x= &quot;10&quot; y= &quot;10&quot;                     label= &quot;{loc.getString('saveBtn')}&quot; /> </mx:Panel> </li></ul>
  36. 36. Stratégies alternatives <ul><li>S'appuyer sur les resources Bundles de Flex : 2 étapes 1. Créer sa propre classe ResourceBundle public class MyResourceBundle extends ResourceBundle {     override protected function getContent():Object {         // C'est ici qu'on implémentera la logique         // d'accès aux données         var properties:Object = {};         properties[&quot;my_key&quot;] = &quot;My value&quot;;         return properties;     } } </li></ul>
  37. 37. Stratégies alternatives <ul><li>2. L'ajouter au resourceManager var moreResources: MyResourceBundle = new MyResourceBundle(&quot;fr_FR&quot;, &quot;moreResources&quot;); // Ajout dynamique de contenu moreResources.content[&quot;CANCEL&quot;] = &quot;Annuler&quot;; resourceManager.addResourceBundle(moreResources); resourceManager.update(); </li></ul>
  38. 38. Le cas d'une application AIR <ul><li>Pas d'intéret particulier à charger dynamiquement les bundles : on va les compiler statiquement avec l'application. Avec AIR 1.1, l'interface d'installation et les boîtes de dialogue ont été traduites en Japonais, Français, Allemand, Chinois (traditionnel et simplifié), Italien, Espagnol, Coréen, Portugais et Russe. </li></ul>
  39. 39. Conclusion <ul><ul><li>Depuis Flex3, l'utilisation des RB côté application est satisfaisant : pas besoin de réinventer la roue </li></ul></ul><ul><ul><li>Le workflow est complexe : préférer un système d'intégration continue, voire des tâches ANT </li></ul></ul><ul><ul><li>La lisibilité du code MXML et AS3 n'est pas excellente, surtout dans l'interface : préférer des clefs courtes et précises </li></ul></ul><ul><ul><li>Si beaucoup de langues, attention à ne pas trop vouloir précharger - mieux vaut charger les bundles au fur et à mesure </li></ul></ul>
  40. 40. Questions / réponses <ul><li>David Deraedt - Flex My Day http://www.dehats.com Centre de formation Regart.net http://www.regart.net Remerciements Lovely Charts http://www.lovelycharts.com </li></ul>

×