SeamFramework.orgCommunity Documentation

Capitolo 16. Internazionalizzazione, localizzazione e temi

Capitolo 16. Internazionalizzazione, localizzazione e temi

16.1. Internazionalizzare un'applicazione
16.1.1. Configurazione dell'application server
16.1.2. Traduzione delle stringhe dell'applicazione
16.1.3. Altre impostazioni per la codifica
16.2. Traduzioni
16.3.
16.4. Definire le etichette
16.5. Mostrare le etichette
16.6. Messaggi Faces
16.7. Fusi orari
16.8. Temi
16.9. Registrare la scelta della lingua e del tema tramite cookies

Seam rende facile la costruzione di applicazioni internazionali. Prima di tutto verranno percorse le varie fasi necessarie per rendere internazionale e tradotta un'applicazione. In seguito si darà un'occhiata al modo in cui Seam gestisce i gruppi di stringhe associate ai componenti (resource bundle).

Un'applicazione JEE consiste di molti componenti ed ognuno di essi deve essere configurato opportunamente affinché l'applicazione venga tradotta.

Partendo dalla base, il primo passo è assicurarsi che il server e il client del database utilizzino la codifica di caratteri corretta per la traduzione. Di solito si vorrà utilizzare UTF-8. Come fare questo non è oggetto di questa guida.

Ci sarà bisogno di tradurre le stringhe per tutti i messaggi dell'applicazione (per esempio le etichette dei campi nelle pagine). In primo luogo occorre assicurarsi che il resource bundle sia codificato utilizzando la giusta codifica di carattere. Per default viene usato ASCII. Benché la codifica ASCII sia sufficiente per molte lingue, essa non fornisce i caratteri per tutte le lingue.

I resource bundles devono essere creati in ASCII, oppure devono utilizzare una notazione Unicode per rappresentare i caratteri Unicode. Poiché un file .properties non viene compilato in byte-code, non c'è modo di dire alla JVM quale codifica caratteri utilizzare. Perciò occorre usare caratteri ASCII oppure usare la notazione Unicode per i caratteri che non fanno parte dell'insieme ASCII. E' possibile rappresentare un carattere Unicode in un file Java usando la notazione \uXXXX, dove XXXX è la rappresentazione esadecimale del carattere.

E' possibile scrivere la traduzione delle etichette (Sezione 16.3, «») nei resource bundles con la codifica del proprio sistema e poi convertire il contenuto del file nel formato con le notazioni Unicode attraverso lo strumento native2ascii fornito con JDK. Questo strumento converte un file scritto nella codifica originale in uno dove i caratteri non-ASCII sono rappresentati come sequenze di notazioni Unicode.

L'uso di questo strumento è descritto qui per Java 5 oppure qui per Java 6. Ad esempio, per convertire un file da UTF-8:

$ native2ascii -encoding UTF-8 messages_cs.properties > messages_cs_escaped.properties

Ogni sessione utente registrata ha associata un'istanza di java.util.Locale (disponibile nell'applicazione come un componente chiamato locale). In condizioni normali non sarà necessario fare alcuna configurazione particolare per impostare la lingua. Seam delega a JSF il compito di determinare la lingua attiva:

E' possibile impostare la lingua manualmente tramite le proprietà di configurazione di Seam org.jboss.seam.international.localeSelector.language, org.jboss.seam.international.localeSelector.country e org.jboss.seam.internationale.localeSelector.variant, ma non c'è una vera buona ragione per farlo.

E' comunque utile consentire all'utente di impostare la lingua manualmente tramite l'interfaccia utente. Seam fornisce una funzionalità per sovrascrivere il linguaggio determinato dall'algoritmo descritto sopra. Tutto ciò che è necessario fare è aggiungere il seguente brano ad una form in una pagina JSP o Facelets:


<h:selectOneMenu value="#{localeSelector.language}">
    <f:selectItem itemLabel="English" itemValue="en"/>
    <f:selectItem itemLabel="Deutsch" itemValue="de"/>
    <f:selectItem itemLabel="Francais" itemValue="fr"/>
    <f:selectItem itemLabel="Italiano" itemValue="it"/>
</h:selectOneMenu>
<h:commandButton action="#{localeSelector.select}"
    value="#{messages['ChangeLanguage']}"/>

Oppure, se si vuole mostrare una lista delle lingue gestite da faces-config.xml, si può usare:


<h:selectOneMenu value="#{localeSelector.localeString}">
    <f:selectItems value="#{localeSelector.supportedLocales}"/>
</h:selectOneMenu>
<h:commandButton action="#{localeSelector.select}"
    value="#{messages['ChangeLanguage']}"/>

Quando l'utente seleziona una voce dal menu a discesa e poi fa click sul bottone di comando, la lingua di Seam e di JSF viene sovrascritta per il resto della sessione.

Tutto ciò porta a domandarsi dove siano definite le lingue gestite. Tipicamente nell'elemento <locale-config> del file di configurazione JSF (/META-INF/faces-config.xml) si indica una lista di lingue per le quali si dispone dei corrispondenti resource bundle. Ad ogni modo si è imparato ad apprezzare che il meccanismo di configurazione dei componenti Seam è più completo di quello fornito in Java EE. Per questa ragione è possibile configurare le lingue gestite e la lingua di default del server usando il componente org.jboss.seam.international.localeConfig. Per usarlo occorre prima dichiarare il namespace XML per il pacchetto international di Seam nel descrittore dei componenti Seam, quindi definire la lingua di default e le lingue gestite come segue:


<international:locale-config default-locale="fr_CA" supported-locales="en fr_CA fr_FR it_IT"/>

Ovviamente se c'è la dichiarazione che una certa lingua è gestita, sarà meglio fornire il resource bundle corrispondente! Nel prossimo capitolo si imparerà come si definiscono le etichette per una lingua specifica.

JSF gestisce l'internazionalizzazione delle etichette e del testo descrittivo nell'interfaccia utente tramite l'uso di f:loadBundle>. Questo approccio è possibile nelle applicazioni Seam. In alternativa è possibile sfruttare i vantaggi offerti dal componente Seam messages per mostrare label costruite tramite modelli con espressioni EL.

Seam fornisce un java.util.ResourceBundle (disponibile all'applicazione come un org.jboss.seam.core.resourceBundle). Occorre rendere disponibili le nostre etichette tradotte tramite questo speciale resource bundle. Per default il resource bundle usato da Seam si chiama messages così che occorre definire le etichette in file chiamati messages.properties, messages_en.properties, messages_en_AU.properties, ecc. Questi file di solito risiedono nella cartella WEB-INF/classes.

Quindi, in messages_en.properties:

Hello=Hello

E in messages_en_AU.properties:

Hello=G'day

E' possibile indicare un nome diverso per il resource bundle impostando la proprietà di configurazione Seam org.jboss.seam.core.resourceLoader.bundleNames. E' possibile persino specificare un elenco di nomi di resource bundle sui quali devono essere ricercati i messaggi (a partire dall'ultimo).


<core:resource-loader>
    <core:bundle-names>
        <value>mycompany_messages</value>
        <value>standard_messages</value>       
    </core:bundle-names>
</core:resource-loader>

Se si vuole definire un messaggio solo per una particolare pagina, è possibile specificarlo in un resource bundle con lo stesso nome dell'identificativo della view JSF, omettendo il / iniziale e l'estensione del file finale. Così è possibile mettere il nostro messaggio in welcome/hello_en.properties se si desidera mostrare il messaggio solo in /welcome/hello.jsp.

E' anche possibile specificare esplicitamente un nome di resource bundle in pages.xml:


<page view-id="/welcome/hello.jsp" bundle="HelloMessages"/>

Quindi possiamo usare i messaggi definiti in HelloMessages.properties in /welcome/hello.jsp.

Le applicazioni Seam sono anche molto facilmente personalizzabili nell'aspetto. Le API per i temi sono molto simili alle API per la traduzione, ma ovviamente questi due concetti sono ortogonali e alcune applicazione gestiscono sia le traduzioni che i temi.

Prima di tutto occorre configurare l'insieme dei temi gestiti:


<theme:theme-selector cookie-enabled="true">
    <theme:available-themes>
        <value>default</value>
        <value>accessible</value>
        <value>printable</value>
    </theme:available-themes>
</theme:theme-selector>

Notare che il primo tema elencato è il tema di default.

I temi sono definiti in file di proprietà con lo stesso nome del tema. Ad esempio, il tema default è definito come un insieme di voci in default.properties. Ad esempio default.properties potrebbe definire:

css ../screen.css
template /template.xhtml

Di solito le voci nel resource bundle di un tema saranno percorsi a fogli di stile CSS o immagini e nomi di modelli facelets (a differenza dei resource bundle per le traduzioni che normalmente contengono testo).

Ora è possibile usare queste voci nella pagine JSP o facelets. Ad esempio, per gestire con un tema il foglio di stile di una pagina facelets:


<link href="#{theme.css}" rel="stylesheet" type="text/css" />

Oppure, quando la definizione della pagina risiede in una sottocartella:


<link href="#{facesContext.externalContext.requestContextPath}#{theme.css}" 
    rel="stylesheet" type="text/css" />

In modo più flessibile, facelets consente di gestire con i temi il modello usato da un <ui:composition>:


<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    template="#{theme.template}">

Così come per selezionare la lingua, c'è un componente che consente all'utente di cambiare liberamente il tema:


<h:selectOneMenu value="#{themeSelector.theme}">
    <f:selectItems value="#{themeSelector.themes}"/>
</h:selectOneMenu>
<h:commandButton action="#{themeSelector.select}" value="Select Theme"/>