Bonjour à tous,
Tout d’abord désolé pour le temps d’absence j’ai été débordé de travail ces derniers temps.
Aujourd’hui un petit article assez court mais qui me semble important car j’ai été assez impressionné par le support de l’internationalisation dans Seam.
Dans le cadre d’un projet développé à l’école et probablement destiné au logiciel libre d’ici un ou deux mois (je ferais des publications pour vous le faire savoir car je pense qu’il y aura du code la dedans qui pourra vous intéresser), j’ai eu à gérer plusieurs langues.
Ce projet consiste en un cartographieur du web. Grosso modo des crawler parcours le web selon une configuration voulu, et en fonction de leurs retours un graph est généré. Vous pouvez alors naviguer dans ce graph au sein d’un applet flash qui vous permet d’ouvrir les pages via un proxy qui contrôle votre navigation dans les pages crawlées.
Souvent mettre un site ou une webapp en plusieurs langue est assez problématique. Le modèle le plus utilisé est celui des fichier de messages_[langue].properties et c’est aussi celui par Seam.
Quand j’ai su que mon projet devrait être internationalisé je me suis dit : galère ça va prendre un temps fou ça.
Et bien je me trompais, voici pourquoi.
Première étape, le selecteur de langue
La première chose est de stocker dans la session utilisateur la langue choisie par l’utilisateur. Et la Seam a tout prévu pour vous : le localeSelector est là pour ça.
Donc pour mettre un selecteur de langue c’est très simple :
<h:form>
<h:selectOneMenu value="#{localeSelector.language}">
<f:selectItem itemLabel="#{messages['org.sweetmap.english']}" itemValue="en"/>
<f:selectItem itemLabel="#{messages['org.sweetmap.french']}" itemValue="fr"/>
</h:selectOneMenu>
<h:commandButton action="#{localeSelector.select}" value="#{messages['org.sweetmap.selectlanguage']}"/>
</h:form>
Et là on vois déjà apparaître quelques extraits de code qui amènent à s’interroger, par exemple :
<f:selectItem itemLabel="#{messages['org.sweetmap.english']}" itemValue="en"/>
En fait Seam intègre un composant messages interrogeable tel que via une EL, qui est lié à la locale choisie dans le locale selector et va chercher le fichier de messages.properties en fonction de cette locale.
Vous l’avez peut être vu quand vous générez un projet avec Seam-Gen celui-ci vous intègre des fichiers de properties tels que messages_fr.properties, messages_en.properties etc …
Par défaut la locale choisie est celle configurée dans votre fichiers faces-config.xml:
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="1.2"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
<application>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>en</supported-locale>
<supported-locale>fr</supported-locale>
</locale-config>
<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
</application>
</faces-config>
Et donc pour mon messages['org.sweetmap.english'] j’ai dans mes fichiers de properties une ligne correspondante telle que : org.sweetmap.english=Anglais.
Voilà, ainsi quelque soit l’endroit ou j’ai du texte à ajouter, au lieu d’écrire ce texte j’écris des EL du style "#{messages['org.sweetmap.menu.themap']}" et je remplis mes fichiers de properties, et l’internationalisation est gérée toute seule. Simple non?
Enfin si côté serveur on a besoin de tester la langue de l’utilisateur, par exemple pour faire une requête ejbql en fonction de la langue, on peut récupérer la locale choisie via cet appel :
LocaleSelector.instance().getLanguage();
Celui-ci retournera une String avec par exemple en ou fr selon la langue.
Dans mon cas pour mes Entités JPA, j’ai choisi de stocker cette String en base afin de pouvoir requêter la base par langue.
Autre info, les locales gérées par Seam sont du type java.util.Locale afin de rester assez générique.
Voilà j’espère que cet article vous a été utile !