PixTMS – La localisation de vos applications

PixTMS, nouvelle extension de Pixlib, permet de réaliser facilement la localisation de vos applications Flash.

PixTMS pour Pixlib Translation Management System va permettre de gérer vos traductions avec le support de fichiers :

  • XML
  • XLIFF
  • MO / PO
  • Fichier de propriétés

Voyons comment cela fonctionne.

Tout d’abord, une présentation rapide du système de classes mis à disposition dans cette librairie.

PXLanguage est le singleton (le pilier) qui va s’occuper d’aller récupérer les traductions et ensuite un ensemble de classes permettant de définir les différents types de données gérés pour les traductions (bundle) :

  • PXXMLLanguageBundle : données XML
  • PXXLIFFLanguageBundle : données au format XLIFF
  • PXPropLanguageBundle : fichier de propriétés
  • PXPOLanguageBundle : données au format PO
  • PXMOLanguageBundle : données binaire MO

Ces classes tourne autour de l’interface principale PXILanguageBundle (et d’une classe abstraite PXLanguageBundle).

Le système de traduction mis en place par PixTMS permet de charger des documents externes, mais aussi d’utiliser des données qui sont packagées lors de la compilation (embeded).

1. Présentation et traductions packagées

Prenons un premier exemple avec l’utilisation de l’extension PixEmbed de Pixlib :

Tout d’abord un fichier XML de traduction rapide :

<file>
 <body>
     <trans-unit id="NAME">Travail de bas niveaux sur Actionscript 3.0</trans-unit>
 </body>
</file>

Comme déjà vu dans une précédente leçon, on va créer nos embed :

package
{
	public class MyEmbed
	{
		[Embed(source="fr-FR.xml", mimeType="application/octet-stream")]
		public var frFR : Class;
 
		[Embed(source="en-US.xml", mimeType="application/octet-stream")]
		public var enUS : Class;
	}
}

 

Et maintenant, on va gérer les traductions à proprement parler :

package
{
	import net.pixlib.core.PXBaseDocument;
	import net.pixlib.embed.PXEmbedEngine;
	import net.pixlib.load.PXResourceLocator;
	import net.pixlib.log.PXDebug;
	import net.pixlib.log.PXTraceLayout;
	import net.pixlib.log.addLogListener;
	import net.pixlib.tms.PXLanguage;
	import net.pixlib.tms.bundles.PXXMLLanguageBundle;
 
	import flash.events.Event;
 
	public class Sample extends PXBaseDocument
	{
		override protected function onDocumentReady() : void
		{
			//On rajoute une sortie pour les messages de Pixlib, ici le classique "trace"
			addLogListener(PXTraceLayout.getInstance());
 
			//On déclare les embed
			PXEmbedEngine.addParser("frFR", PXEmbedEngine.parseXML);
			PXEmbedEngine.addParser("enUS", PXEmbedEngine.parseXML);
			PXEmbedEngine.embed(MyEmbed);
 
			//On récupère le singleton
			var lang : PXLanguage = PXLanguage.getInstance();
 
			//On ajoutes 2 bundles en utilisant des bundles XML (<em>PXXMLLanguageBundle</em>) et
			//on récupère les données XML brute depuis nos ressources.
			lang.addBundle(new PXXMLLanguageBundle("fr-FR", PXResourceLocator.getInstance().locateXML("frFR")));
			lang.addBundle(new PXXMLLanguageBundle("en-US", PXResourceLocator.getInstance().locateXML("enUS")));
 
			//On écoute les changements de langue possible
			lang.addEventListener(PXLanguage.onChangeEVENT, _onChange);
 
			//On définie la langue courante, ce qui aura pour effet de charger
			//la traduction automatiquement. Et l'évènement <em>#<strong>onChangeEvent</strong></em> sera
			//envoyé
			lang.current = "fr-FR";
		}
 
		private function _onChange(event : Event) : void
		{
			//On récupère la traduction identifiée par "NAME" dans notre fichier XML.
			PXDebug.DEBUG(PXLanguage.getInstance().getString("NAME"), this);
		}
	}
}

2. Les traductions externes

Bien évidement, il est aussi possible de charger des traductions depuis l’extérieur.

package
{
	import net.pixlib.core.PXBaseDocument;
	import net.pixlib.log.PXDebug;
	import net.pixlib.log.PXTraceLayout;
	import net.pixlib.log.addLogListener;
	import net.pixlib.services.PXHTTPService;
	import net.pixlib.tms.PXLanguage;
	import net.pixlib.tms.bundles.PXLoadableBundle;
	import net.pixlib.tms.bundles.PXXLIFFLanguageBundle;
 
	import flash.events.Event;
 
	public class Sample extends PXBaseDocument
	{
		override protected function onDocumentReady() : void
		{
			//On rajoute une sortie pour les messages de Pixlib, ici le classique "trace"
			addLogListener(PXTraceLayout.getInstance());
 
			//On récupère le singleton
			var lang : PXLanguage = PXLanguage.getInstance();
 
			//On charge nos traductions en utilisant un service HTTP
			lang.addBundle(new PXLoadableBundle(new PXXLIFFLanguageBundle("fr-FR"), new PXHTTPService("fr-FR.xlf")));
			lang.addBundle(new PXLoadableBundle(new PXXLIFFLanguageBundle("en-US"), new PXHTTPService("en-US.xlf")));
 
			lang.addEventListener(PXLanguage.onChangeEVENT, _onChange);
			lang.current = "en-US";
		}
 
		private function _onChange(event : Event) : void
		{
			PXDebug.DEBUG(PXLanguage.getInstance().getString("NAME"), this);
		}
	}
}

Pour le chargement externe, on utilise donc un bundle particulier qui est le PXLoadableBundle.

Ce bundle prend comme argument, le type de traduction à gérer (XML, XLIFF, PO, etc) sous forme de PXILanguageBundle et ensuite un PXService permettant de définir comment seront chargées ces traductions.

 

3. Gestion des fichiers de traductions

Afin de pouvoir découper vos traductions il est possible de définir un identifiant pour chaque bundle.

Pratique pour créer des traductions spécifiques pour telle ou telle partie d’une application.
Cet identifiant est un argument du constructeur :

//Bundle par défault (sans identifiant explicite)
lang.addBundle(new PXLoadableBundle(new PXMLLanguageBundle("fr-FR"), new PXHTTPService("fr/home.xml")));
 
//bundles dédiés
lang.addBundle(new PXLoadableBundle(new PXMLLanguageBundle("fr-FR", null, "home"), new PXHTTPService("fr/home.xml")));
lang.addBundle(new PXLoadableBundle(new PXMLLanguageBundle("fr-FR", null, "error"), new PXHTTPService("fr/error.xml")));

Ensuite, pour récupérer les traductions, il suffit de cibler le bundle désiré :

private function _onChange(event : Event) : void
{
	//On récupère dans le bundle par défault
	PXDebug.DEBUG(PXLanguage.getInstance().getString("NAME"), this);
 
	//On récupère dans le bundle "home"
	PXDebug.DEBUG(PXLanguage.getInstance().getString("MESSAGE", "home"), this);
}

 

4. Récupérer une traduction

Comme vu dans les divers exemple ci dessus, on utilise la méthode #getString() afin de récupérer la valeur d’une traduction dans le langage et le bundle désiré. Cette méthode gère aussi 2 paramètres optionnels supplémentaire afin de mieux contrôler la récupération des données.

Le 3 ème paramètre est la valeur par défaut à retourner dans le cadre où la traduction demandée n’existe pas :

private function _onChange(event : Event) : void
{
	//On récupère dans le bundle par défault. Si 'NAME' n'est pas défini
	//alors on retournera "Pixlib"
	PXDebug.DEBUG(PXLanguage.getInstance().getString("NAME", null, "Pixlib"), this);
}

Et le 4 ème paramètre lui est un tableau de substitution que l’on peut envoyer directement.

Une fois la traduction retrouvée, la substituion avec les valeurs de ce tableau sera réalisé. Les substitutions fonctionnant sous le modèle défini par la méthode PXStringUtils#substitute().

private function _onChange(event : Event) : void
{
	//On récupère dans le bundle "home", et on réalise une substitution sur la traduction.
	//Dans le fichier de traduction, notre texte devra être formaté par exemple : My name is {0} on {1}
	PXDebug.DEBUG(PXLanguage.getInstance().getString("MESSAGE", "home", null, ["Pixlib", "AS3"]), this);
}

5. Les téléchargements

Happy coding with Pixlib

This entry was posted in Extension, Framework, Tutorial and tagged , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" cssfile="">