1 Introduction
L’objectif de cet article n’est pas de fournir la meilleure solution pour assurer l’auto-traduction d’un site Web en ASP.NET, mais de fournir un exemple simple.
L’exemple a été conçu sur la base du Framework 1.1 sur une machine Windows 2003 Server édition standard US.
L’article se divisera en deux parties :
Ø Etape 1 : l’auto-traduction des contrôles de page
Ø Etape 2 : la traduction des informations en base
Pour l’instant cet article se concentre uniquement sur l’étape 1. Un autre article verra le jour prochainement pour l’étape 2.
2.1 Préambule
La première démarche, lorsqu’un site Web doit être traduit, est de se poser une série de bonnes questions. Ces dernières sont fondamentales pour la réussite de votre projet :
1. Quelles sont les langues à prendre en compte ? En déduire les alphabets, les cultures, l’orientation des textes.
2. L'ergonomie envisagée est-elle conforme à toutes les cultures ? Si ce n’est pas le cas, il faudra envisager une uniformisation par recherche des dénominateurs communs des différentes cultures. Sinon, il faudra envisager une spécialisation des interfaces.
3. Que faut-il traduire ?
a. Les labels, les dates, les unités monétaires, les images
b. Les données en base
i. quelles données précisément ? Toutes ? Une partie seulement ?
ii. Faut-il prévoir un encodage UNICODE des champs traduits en base ?
iii. Quel est le mode de stockage : par champ fixe, par une ou plusieurs tables de traduction fonction des langues, par un champ stockant des informations en XML ?
4. L’application doit-elle être complètement auto-traduite ou bien peut-on envisager une "maintenance humaine" pour l'ajout de nouvelle langues ?
En fait, cette série de questions en amène une autre qui me parait fondamentale, à savoir jusqu’où aller, ou du moins jusqu’où ne pas aller trop loin dans l’automatisation de la traduction du site. En effet, techniquement tout est envisageable, mais pour des raisons de coût initial et de performance sur l’utilisation de l’application, les contraintes sont souvent revues à la baisse ! Mais c’est là une autre histoire…
2.2 Architecture envisagée
L’architecture de l’exemple est la suivante :
Au moment du rendu des différents contrôles, la classe « TemplateTranslation » sera chargée de rechercher les éventuelles traductions des différents contrôles aux valeurs statiques, c'est-à-dire non issus de la base de données. Il serait possible de stocker les traductions :
Ø Soit dans des fichiers de ressources et, afin d’être un peu plus générique, il faudrait également stocker deux informations au sein du fichier de ressource :
· Le nom de la propriété à mettre à jour
· La valeur de la propriété
Afin de distinguer le nom de la propriété, de la valeur, on devrait utiliser un code séparateur, par exemple : « //// ».
Ø Soit dans un fichier de traduction XML. C’est l’optique que j’ai choisie dans le cadre de cet exemple.
Voici un exemple d’instance de ce fichier XML avec trois langues :
<?xml version="1.0" encoding="utf-8" ?>
<pages>
<page path="/Internationalization/default.aspx">
<controls>
<control id="lblLanguage">
<properties>
<property culture="fr-FR" name="Text" value="Langue :" transformer="" />
<property culture="en-US" name="Text" value="Language:" transformer="" />
<property culture="de-DE" name="Text" value="Sprache :" transformer="" />
<property culture="fr-FR" name="BackColor" value="white" transformer="Internationalization.ColorTransformer.Apply" />
<property culture="en-US" name="BackColor" value="gray" transformer="Internationalization.ColorTransformer.Apply" />
<property culture="de-DE" name="BackColor" value="green" transformer="Internationalization.ColorTransformer.Apply" />
</properties>
</control>
<control id="Image1">
<properties>
<property culture="fr-FR" name="ImageUrl" value="images/image-fr-FR.gif" transformer="Internationalization.UrlTransformer.Apply" />
<property culture="en-US" name="ImageUrl" value="images/image-en-US.gif" transformer="Internationalization.UrlTransformer.Apply" />
<property culture="de-DE" name="ImageUrl" value="images/image-de-DE.gif" transformer="Internationalization.UrlTransformer.Apply" />
</properties>
</control>
<control id="img1">
<properties>
<property culture="fr-FR" name="Src" value="images/image-fr-FR.gif" transformer="Internationalization.UrlTransformer.Apply" />
<property culture="en-US" name="Src" value="images/image-en-US.gif" transformer="Internationalization.UrlTransformer.Apply" />
<property culture="de-DE" name="Src" value="images/image-de-DE.gif" transformer="Internationalization.UrlTransformer.Apply" />
</properties>
</control>
<control id="txtTest">
<properties>
<property culture="fr-FR" name="Text" value="Mon texte !" transformer="" />
<property culture="en-US" name="Text" value="My Text!" transformer="" />
<property culture="de-DE" name="Text" value="mein Text !" transformer="" />
</properties>
</control>
</controls>
</page>
</pages>
Les informations sont classées par page, par contrôle, par propriété et par culture. Enfin, on notera la possibilité d’appliquer une transformation sur chaque contrôle sous la forme d’un nom de méthode qui sera dynamiquement appliquée lors de la traduction (pour peu qu’elle respecte une signature donnée : une fonction avec un paramètre en entrée qui retourne la valeur de la propriété du contrôle).
Dans le cadre de cet exemple, j’ai créé deux Transformers :
Ø ColorTransformer : pour appliquer une transformation permettant, à partir du nom d’une couleur, de renvoyer le type correspondant
Ø UrlTransformer : pour appliquer une transformation au niveau d’une URL
Les informations contenues dans le fichier XML sont mises en cache avec une dépendance sur le fichier XML, ce qui permet ainsi de réactualiser le cache automatiquement lorsque le fichier de configuration change. Au sein de l’exemple, la classe « ParamCache » se charge de cette gestion.
La classe « TemplateTranslation » est chargée de l’auto-traduction des contrôles en fonction des données décrites dans le fichier XML.
2.3 La base de données
L’article suivant traitera de cette problématique.
2.4 Conclusion
Cette première partie de l’article a permis d’illustrer un exemple simple d’auto-traduction des éléments statiques d’un formulaire Web. Bien entendu, cet exemple pourra être grandement amélioré, notamment sur les points suivants :
· Tester un peu plus en avant le code !
· Externaliser les composants de traduction dans une assembly de type DLL
· Une optimisation (fichier XML) pourrait être d’éviter de dupliquer le nom de la propriété par culture
Il y a sûrement plein d’autres choses à améliorer et, là encore, je vous fais confiance sur le sujet !