La soluzione adottata
Di fatto Rails non fornisce un supporto nativo al multilingua, ma si appoggia all’ottimo plugin Globalize rilasciato da Josh Harvey sotto la licenza MIT (la stessa sotto la quale è rilasciato Rails).
Esso supporta la traduzione in più lingue sia dei dati presenti nei database, che delle informazioni legate ai controller e ai model, ed inoltre permette la localizzazione del tempo, delle date e dei numeri. Per rendere il tutto più interessante, dimostreremo come tutto ciò possa funzionare costruendo un’applicazione di esempio, che pur non avendo un vero scopo preciso, ci aiuterà a vedere in opera le funzionalità offerte da Globalize.
Perché costruire un’applicazione multilingua
Se qualcuno di voi non fosse ancora convinto dell’utilità portata dall’utilizzo della globalizzazione all’interno della nostra applicazione, elenchiamo alcuni dei problemi più importanti che essa ci permette di risolvere.
- Formato data ed ora. Una data che in Italia potrebbe essere presentata nel formato 10 Giugno 2005, negli Stati Uniti potrebbe essere presentata nel formato 2005, June 10.
- Formato valuta. Una valuta che in Italia potrebbe essere presentata nel formato 10.000,25 €, negli Stati Uniti potrebbe essere presentata nel formato 10,000.25 $, in cui cambiano l’ordine dei punti e delle virgole, oltre che al simbolo della valuta.
- Direzione del testo. Mentre nei paesi europei siamo abituati a leggere il testo da sinistra a destra, in alcuni paesi asiatici la lettura avviene da destra a sinistra.
- Immagini e colori. La personalizzazione della nostra applicazione oltre che essere legata ai contenuti di tipo testuali, deve essere vicina anche alla cultura del popolo al quale ci poniamo.
- Numeri di telefono, codici postali, indirizzi e molto altro ancora!
Iniziamo con qualche richiamo teorico
Prima di vedere come implementare un’applicazione multilingua, introduciamo una serie di concetti che ci serviranno a comprendere meglio di che cosa stiamo parlando e il perché tutto questo venga considerato così importante. Chi pensa di avere già queste conoscenze nel proprio bagaglio, o chi desidera subito analizzare il funzionamento di Globalize può saltare questo paragrafo. Ne consigliamo invece la lettura a chi non ha mai affrontato queste tematiche, in quanto spesso si rischia di fare confusione tra concetti che sono sì simili tra loro, ma che hanno sottili ed importanti differenze.
- L’ internazionalizzazione, spesso chiamata nella forma abbreviata i18n, consiste nell’adattamento della nostra applicazione affinché essa permetta una gestione multilingua. Chiariamo l’idea considerando l’esempio di un’applicazione di e-commerce, in cui possiamo vedere l’internazionalizzazione come la creazione di un pannello di amministrazione che permetta l’inserimento delle diverse lingue in cui i nostri prodotti verranno proposti.
- La localizzazione, spesso chiamata nella forma abbreviata L10n, invece consiste nell’adattamento della nostra applicazione ad uno specifico mercato, che noi chiameremo locale. Riprendendo l’esempio dell’applicazione e-commerce, la localizzazione consiste nell’inserimento (attraverso il pannello di amministrazione definito nella fase di internazionalizzazione) delle descrizioni dei prodotti nelle lingue desiderate.
- La globalizzazione, spesso chiamata nella forma abbreviata g11n, non fa altro che riunire le due nozioni appena esaminate ed è il termine che noi utilizzeremo nel proseguo dell’articolo.
| Andiamo in profondità… |
| Prima di proseguire spieghiamo velocemente il significato dello strano modo in cui sono definiti gli acronimi appena visti. Solitamente le sigle i18n, L10n e g11n (composti da lettere e numeri) non si trovano nel web, dove siamo più abituati a sequenze di lettere, ognuna delle quali è semplicemente l’iniziale di una parola (ad esempio RoR sta proprio per Ruby on Rails). In questo caso invece si è deciso di prendere in considerazione solamente la prima e l’ultima lettera dei tre concetti visti, inserendo nel mezzo il numero delle lettere che compongono la parola in inglese. Eliminiamo eventuali dubbi guardando l’immagine che segue.
|
Inizio dei giochi! Installiamo Globalize
Dopo aver fatto qualche accenno a livello teorico, eccoci arrivare alla parte più interessante del nostro articolo, cioè quella in cui spiegheremo passo passo come poter implementare la globalizzazione all’interno della nostra applicazione.
Prima di tutto abbiamo bisogno di un’applicazione Rails, in cui sia già stata settata la configurazione del database. Questa risulta una prerogativa necessaria, in quando nel momento in cui installeremo Globalize verranno create automaticamente 3 tabelle, necessarie per la gestione multilingua. Quindi una volta effettuata la configurazione iniziale, potremo aggiornare la nostra applicazione.
1
2
3
4
5
6
7
8
|
# spostamento all'interno del progetto dictionary
E:\> cd dictionary
# installazione plugin globalize (necessita connessione ad internet attiva)
E:\dictionary> ruby script/plugin install http://svn.globalize-rails.org/svn/globalize/globalize/branches/for-1.1
# creazione tabelle per la gestione della globalizzazione
E:\dictionary> rake globalize:setup |
A seguito di aggiornamenti del progetto, in alcune situazioni il comando ruby script/plugin install potrebbe non andare a buon fine. In questo caso dovremo procurarci Subversion e digitare i seguenti comandi.
1
2
3
4
5
|
# spostamento all'interno della directory vendor/plugins
E:\dictionary>cd vendor/plugins
# installazione plugin globalize (necessita connessione ad internet attiva)
E:\dictionary\vendor\plugins>svn export svn://svn.globalize-rails.org/globalize/branches/for-1.1 globalize |
Perché queste nuove tabelle
Se ora andiamo a curiosare all’interno del database dictionary_development (il database utilizzato per la nostra applicazione) troveremo tre nuove tabelle che verranno utilizzate per la gestione del contenuto multilingua della nostra applicazione. Andiamo ad esaminarle per capire a fondo quali siano i loro ruoli.

- globalize_countries elenca 239 nazioni e per ognuna di esse definisce alcuni valori necessari per la formattazione della valuta, della data e molto altro.
- globalize_languages elenca 186 linguaggi e per ognuno di essi definisce alcuni valori come la direzione del testo o il nome nativo della lingua (ad esempio nel caso della lingua tedesca, il nome nativo è Deutsch).
- globalize_translations elenca 3420 stringhe già tradotte e pronte all’uso, ed è su questa tabella che noi apporteremo il maggior numero di modifiche, andando a definire di volta in volta le traduzioni di cui avremo bisogno.
Un primo semplice esempio
Una volta installato il plugin ed analizzate le tabelle su cui esso si basa, il secondo passo consiste nel settare la lingua che verrà utilizzata di default nella nostra applicazione. Siccome si tratta di un articolo dedicato ad un pubblico italiano, non potevamo che settare la lingua ed il locale italiano.
1
2
3
4
5
6
7
|
# Estratto del file config/environment.rb
...
# Include your application configuration below
include Globalize # inclusione del plugin Globalize
Locale.set_base_language('it-IT') # settaggio della lingua di default
Locale.set('it-IT') # settaggio del locale di default |
Prima di procedere con lo sviluppo della nostra applicazione di esempio, ci conviene controllare il corretto funzionamento del plugin Globalize. Per farlo la soluzione più rapida è quella di creare un controller ed un’azione di prova, all’interno della quale scriveremo il codice necessario a stampare una data (Time.now). A questa punto aggiungeremo il metodo localize, il quale gestirà in automatico la formattazione della data.
1
2
3
4
5
6
7
8
|
# Estratto del file app/controllers/test_controller.rb
class TestController < ApplicationController
def index
# stampa della data nel linguaggio di default
render :text => Time.now.localize("%A %d %B %Y")
end
end |
Dopo aver avviato il web server WEBRick, possiamo andare a vedere il nostro primo risultato digitando sul browser l’indirizzo http://localhost:3000/test. Se tutto andrà a buon fine ciò che otterremo sarà una data scritta in italiano simile a Mercoledì 21 Giugno 2006.
A questo punto la nostra curiosità dovrebbe portarci a vedere che cosa accade nel momento in cui cambiamo il Locale della della nostra applicazione. Proviamo quindi a settare quello inglese e poi andiamo a vedere il risultato ottenuto.
1
2
3
4
5
6
7
8
9
|
# Estratto del file app/controllers/test_controller.rb
class TestController < ApplicationController
def index
# stampa della data nella lingua inglese
Locale.set('en-US')
render :text => Time.now.localize("%A %d %B %Y")
end
end |
In questo caso, dopo aver aggiornato la nostra pagina web, il risultato sarà simile a Wednesday 21 June 2006. Non male se pensiamo che le righe di codice scritte fino ad ora non sono nemmeno una decina!
Facciamo qualcosa in più
Arrivati a questo punto abbiamo potuto osservare come il plugin funzioni correttamente, ma vorremmo fare qualcosa in più. Cerchiamo allora di affiancare alla data un breve e semplice messaggio di benvenuto, questa volta utilizzando il metodo t (dove la t sta per translate).
Per rispettare il paradigma MVC (Model View Controller) sposteremo questo nuovo messaggio, e la data che avevamo precedentemente definito, all’interno della vista index.rhtml (la vista associata di default all’azione index). Ricordiamo infatti l’importanza di separare la logica applicativa, che sta nelle azioni, e la logica di presentazione, che sta nelle viste.
1
2
3
4
5
6
7
8
9
|
# Estratto del file app/controllers/test_controller.rb
class TestController < ApplicationController
def index
# settaggio lingua italiana
Locale.set('it-IT')
# rendering automatico della vista index.rhtml
end
end |
1
2
3
4
|
# Estratto del file app/views/test/index.rhtml
<%= 'Benvenuti'.t %> -
<%= Time.now.localize("%A %d %B %Y") %> |
Il risultato in questo caso sarà simile a Benvenuti – Mercoledì 21 Giugno 2006.
| Andiamo in profondità… |
| Prima di proseguire ci soffermeremo un minuto su un particolare che forse ha già attirato la nostra attenzione. Questo particolare consiste nella presenza del metodo Locale.set(‘it-IT’) all’interno dell’azione index. La domanda che dovremmo porci è la seguente: perché settare la lingua italiana se è già quella di default? La risposta è tanto semplice quanto importante, in quanto il caricamento della lingua di default, che ricordiamo essere definita nel file environment.rb, avviene solo in fase di avvio dell’applicazione (cioè all’avvio del web server). Se non settassimo la lingua italiana nell’azione index, la lingua attiva rimarrebbe quella inglese (questo perché in precedenza avevamo settato il locale en-US per vedere la data nella formattazione usata in america). |
Ora proseguiamo seguendo i passi già fatti precedentemente per la data, cioè cambiando nell’azione index il locale italiano con quello americano en-US. Il risultato ottenuto sarà Benvenuti – Wednesday 21 June 2006. A prima vista sembra che qualcosa non funzioni, in quanto ci aspettavamo il messaggio Welcome – Wednesday 21 June 2006.
Il risultato ottenuto in realtà è corretto (non vi è alcun problema con Globalize); siamo noi che dobbiamo dare maggiori informazioni al plugin. Esso infatti per riuscire a tradurre la parola benvenuto deve cercare tale informazione nella tabella globalize_translations, ma non trovandola ha lasciato il messaggio originale in italiano (l’unico a disposizione).
Dobbiamo quindi inserire un nuovo record per fare in modo che la traduzione abbia esito positivo. Le strade possibili sono due: inserire direttamente quanto desiderato attraverso una query, oppure utilizzare il metodo set_translation offerto da Globalize per effettuare traduzioni al volo in pochi secondi (naturalmente noi useremo questa strada).
I parametri da passare al metodo saranno i seguenti:
- la stringa da tradurre
- la lingua in cui vogliamo tradurla
- la traduzione vera e propria
Ecco il codice necessario per creare la traduzione di benvenuti in welcome.
1
2
3
4
5
6
7
8
9
10
11
|
# Estratto del file app/controllers/test_controller.rb
class TestController < ApplicationController
def index
Locale.set('en-US')
# creazione della traduzione prima del rendering della vista
Locale.set_translation('Benvenuti',
Language.pick('en-US'),
'Welcome')
end
end |
Il metodo set_translation non fa altro che creare un nuovo record all’interno della tabella globalize_translation (simile a quello che possiamo vedere nella figura seguente). Ora la traduzione, che prima era incompleta, avverrà correttamente ed il risultato che ottenuto sarà il tanto desiderato Welcome Wednesday 21 June 2006

Alternative a Globalize
Sebbene in questo articolo abbiamo discusso della localizzazione, dell’internazionalizzazione e della globalizzazione basandoci unicamente sul plugin Globalize, va detto che questa non è l’unica soluzione disponibile (seppure al momento venga considerata la migliore tra tutte).
Chiunque desideri approfondire l’argomento può vedere ad altre soluzioni riassunte in pagina di comparazione presente nel wiki di rubyonrails.org nella quale vengono confrontati tutti i sistemi che attualmente permettono la gestione di contenuti multilingua all’interno di applicazioni Rails
Conclusioni
Riassumendo abbiamo dato un’introduzione completa al funzionamento del plugin Globalize, lo strumento utilizzato all’interno di Rails per la gestione dei contenuti multilingua. L’articolo, seppur introduttivo, ha voluto affrontare quanto segue:
- il significato dei concetti alla base dei sistemi multilingua
- l’installazione di Globalize
- la gestione delle caratteristiche più comuni di Globalize
Inoltre abbiamo volutamente deciso di affrontare ed analizzare il come certe cose vengono fatte, analizzando quindi aspetti non strettamente necessari per utilizzare Globalize, ma preziosi per capirne a fondo il funzionamento. In questo modo abbiamo voluto fornire una solida base per i futuri articoli (questo non è che il primo di una serie) in cui cercheremo di avvicinarci passo passo alle problematiche che spesso vengono a crearsi nel momento in cui iniziamo creare un’applicazione destinata a tutte le popolazioni del mondo! Rimanete sintonizzati su The Ruby Mine!
Licenza
Questo articolo è coperto dalla licenza Creative Commons Attribution-NonCommercial-NoDerivs 2.5 Italy.