Projets
Pages enfant
  • 3.1 Internationalisation

Comparaison des versions

Légende

  • Ces lignes ont été ajoutées. Ce mot a été ajouté.
  • Ces lignes ont été supprimées. Ce mot a été supprimé.
  • La mise en forme a été modifiée.
Astuce
titleRelu

Relecture RB faite le 17/02/2011

L'internationalisation est native dans esup-commons. L'intérêt n'est pas seulement de fournir une application en plusieurs langages ; l'externalisation de toutes les chaînes de caractères, et la possibilité d'utiliser simultanément plusieurs fichiers de chaînes (les bundles) permet de simplifier la personnalisation des applications par les administrateurs.


Sommaire :

Sommaire
maxLevel3

Principes

Configuration

L'internationalisation est définie dans le fichier de configuration /properties/i18n/i18n.xml. On y trouvera par exemple :

Bloc de code
<bean
    id="i18nService"
    class="[...].commons.services.i18n.BundlesCachingI18nServiceImpl"
    >
  <property name="bundleBasenames">
    <list>
      <value>properties/i18n/bundles/Commons</value>
      <value>properties/i18n/bundles/Messages</value>
      <value>properties/i18n/bundles/Custom</value>
    </list>
  </property>
</bean>

La propriété bundleBasenames donne la liste des fichiers de messages à utiliser. Chaque valeur de la liste correspond à la racine du chemin du fichier de message dans le classpath. Par exemple, on cherchera pour la valeur Custom les fichiers Custom_<locale>.properties ou à défaut Custom.properties.Par convention, on groupera tous les fichiers de messages dans le répertoire /properties/i18n/bundles.

Implémentations disponibles

esup-commons offre plusieurs implémentations afin de gérer l'internationalisation des applications :

  • BundleI18nServiceImpl lit les chaînes de caractères depuis un unique fichier de messages.
  • BundleCachingI18nServiceImpl étend BundleI18nServiceImpl. Elle permet la mise en cache des chaînes de caractères lues depuis le fichier de messages, pour des raisons de performance.
  • BundlesI18nServiceImpl lit les chaînes de caractères depuis plusieurs fichiers de messages.
  • BundlesCachingI18nServiceImpl étend BundlesI18nServiceImpl en apportant des fonctionnalités de cache, pour les mêmes raisons de performance.

C'est cette dernière implémentation qui est généralement conseillée car elle permet la personnalisation locale des applications par les administrateurs sans modifier les fichiers distribués par les développeurs.

Préconisations d'usage

Nommage des bundles

Les fichiers de messages sont lus dans l'ordre où ils apparaissent dans le fichier de configuration. Chaque entrée d'un fichier peut être surchargée par la même entrée définie dans le fichier suivant.

Les fichiers Commons_.properties font partie du projet esup-commons, ils ne doivent pas être modifiés par les développeurs d'applications.

Si le développeur a besoin de surcharger une entrée de ce fichier, il peut le faire grâce aux fichiers Messages_.properties. C'est aussi dans ce fichier qu'il mettra tous les messages relatifs à son application.

Les fichiers Custom_.poperties* permettent à l'exploitant de surcharger les messages livrés avec l'application (qu'il s'agisse de messages de esup-commons ou de l'application). Typiquement, ce fichier devrait être repris par la tâche ant recover-config lors d'une mise à jour. Pour cela, l'exploitant ajoutera une entrée correspondant à ce fichier dans le paramètre custom.recover.files de son fichier build.properties.

exercice
Surcharger un bundle
Surcharger un bundle

Surcharger dans Custom_fr.properties une des entrées de Messages_fr.properties et tester.

solution

Par exemple nous allons modifier le message de bienvenue présent dans le fichier Messages_fr.properties.

Bloc de code
WELCOME.TITLE = Bienvenue

Dans Custom_fr.properties ajouter la clef WELCOME.TITLE et modifier son contenu :

Bloc de code
WELCOME.TITLE = Bienvenue sur l'application de formation.



Modification des fichiers de messages

Pour modifier les fichiers de messages il est recommandé d'utiliser Ressource Bundle Editor (RBE). Il permet notamment d'éditer plusieurs fichiers, correspondants à plusieurs langues, en même temps.Les messages enregistrés dans ces fichiers peuvent contenir des paramètres qui seront dynamiquement renseignés lors de l'exécution. Ces paramètres apparaissent dans les messages sous cette forme :

Bloc de code
{n}

avec n commençant à 0. Exemple :

Bloc de code
L''utilisateur {0} est maintenant gestionnaire du service {1}.
Remarque

Noter ci-dessus l'échappement des apostrophes lorsque la chaîne contient un ou plusieurs paramètres.

Bloc de code
L''utilisateur {0} est maintenant gestionnaire du service {1,choice,0#annuaire|1#helpdesk}.
Remarque

Dans l'exemple ci-dessus, le paramètre 1 ne peut avoir que 2 valeurs : soit annuaire, soit helpdesk.

Ajout d'un langage

L'ajout d'un langage se fait dans le fichier de configuration /properties/jsf/application.xml. Il suffit ensuite d'écrire le bundle correspondant.

exercice
Ajouter un langage
Ajouter un langage

Ajouter le langage japonais et traduire tout esup-commons (clin d'œil)



Externalisation des chaînes sans internationalisation

Comme vu en introduction de cette partie, externaliser les chaînes sans internationaliser conserve un intérêt pour la distribution des applications : faciliter la personnalisation locale des applications là où elles sont portées.

Dans ce cas, on pourra simplement utiliser un seul fichier de ressources, correspondant au langage déclaré.

Utilisation

Dans une vue

JSF

La balise <f:view> propose un attribut locale qui permet de spécifier la langue à utiliser. Cette information est généralement donnée par un contrôleur. On trouvera par exemple en entête des pages :

Bloc de code
<f:view locale="#{sessionController.locale}">

La balise <f:view> positionnera un tableau associatif qui contiendra tous les messages de messages. Ce tableau sera accessible sous le nom msgs et est utilisable dans toute la vue, par exemple :

Bloc de code
<e:text value="#{msgs['MANAGERS.TEXT.PAGES']}">
  <f:param value="#{controller.paginator.firstVisibleNumber + 1}"/>
  <f:param value="#{controller.paginator.lastVisibleNumber + 1}"/>
  <f:param value="#{controller.paginator.totalItemsCount}"/>
</e:text>

Les balises <f:param> permettent de passer les valeurs des paramètres à insérer dans les messages.

Spring MVC

TODO

Depuis un contrôleur (Java)

Par héritage, toute classe (métier ou contrôleur) qui étend AbstractApplicationAwareBean bénéficie des services de AbstractI18nAwareBean et peut appeler ses méthodes d'internationalisation.

 
On utilise cela en particulier pour les messages (d'information ou d'erreur) lancés par les contrôleurs et affichés sur les vues JSF à l'aide de la balise <h:messages>. On utilisera par exemple :

Bloc de code
addErrorMessage(null, "MANAGERS.MESSAGE.USER_NOT_FOUND", userId);

On utilisera également cette fonctionnalité à toute autre fin en accédant directement aux fichiers de messages de cette manière :

Bloc de code
String msg = getString("MY.MESSAGE");

On peut également passer des paramètres à la méthode getString(), ainsi qu'une locale (si l'on souhaite une locale différente de la locale courante), qui est donnée par ma méthode getLocale().

Changement des messages d'erreur par défaut de JSF

Pour modifier les messages d'erreurs par défaut ou les internationaliser, il faut écrire un fichier JsfMessage_fr.properties dans le répertoire /properties/i18n/bundles et ajouter :

Bloc de code
<message-bundle>properties/i18n/bundles/JsfMessages</message-bundle>

au fichier /properties/jsf/application.xml pour que JSF prenne en charge ce nouveau bundle.

Par exemple lorsque l'on utilise les validations implicites avec l'attribut required="true" au lieu d'avoir le message « une donnée est requise », on pourra avoir un message personnalisé en indiquant les messages suivants dans le fichier JsfMessages.properties :

Bloc de code
javax.faces.component.UIInput.REQUIRED = Erreur de validation
javax.faces.component.UIInput.REQUIRED_detail = "et {0} alors !!!