#138 I18n
- Download:
- source codeProject Files in Zip (94.3 KB)
- mp4Full Size H.264 Video (15.3 MB)
- m4vSmaller H.264 Video (9.06 MB)
- webmFull Size VP8 Video (19.9 MB)
- ogvFull Size Theora Video (19.5 MB)
L’internazionalizzazione (i18n) è stata una delle nuove funzionalità introdotte da Rails 2.2. In questo episodio vi mostreremo come usarla, rendendo la pagina seguente in grado di mostrarsi in più di una lingua:
Quando un utente si registra per usare il nostro sito, vorremmo dargli la possibilità di scegliere la lingua che desidera usare per il sito. Per questo sito di e-commerce, gli daremo la possibilità di scegliere tra Inglese e Wookieespeak.
Useremo il plugin Restful Authentication per gestire i nostri utenti e la form seguente è quella generata dal plugin. Abbiamo aggiunto un nuovo campo al modello User
, chiamato language
e abbiamo anche aggiunto una tendina alla form che permette all’utente di impostare la propria lingua preferita. Il valore di ciascuna opzione è un codice di due lettere che, per gli scopi di questo esempio, abbiamo cablato nel codice della vista:
<li> <%= form.label :language, "Language" %> <%= form.select :language, [['English', 'en'], ['Wookieespeak', 'wk']] %> </li>
Creazione dei locale
Le applicazioni create con Rails 2.2 o superiore hanno una cartella chiamata locales
sotto la cartella config
ed è qui che vanno messi i file di internazionalizzazione per le lingue che l’applicazione intende supportare. I testi in lingua sono salvati in un file YAML: ci sarà già un file di esempio per l’inglese, chiamato en.yml
.
Per internazionalizzare la nostra pagina dobbiamo per prima cosa copiare tutti i testi che desideriamo tradurre dalla pagina dei prodotti al file en.yml
:
en: welcome: title: "Welcome" paragraph: "Thank you for visiting our store. Please browse through the products below and buy some stuff. You'll love the unique quality and workmanship put into these items." products: title: "Products" released: "Released"
Si noti che le chiavi possono essere innestate, in modo tale da poter dividere i testi in due sezioni, welcome
e products
. Sistemati i testi in inglese, la cosa da fare è ora di creare un file Wookieespeak che contenga le traduzioni. Queste finiranno pertanto in un file chiamato wk.yml
nella stessa cartella:
wk: welcome: title: "Wyah" paragraph: "Wyaaaaaa. Ruh ruh. Huwaa muaa mumwa. Wyogg, ur oh. Wua ga ma uma ahuma ooma. Ruh gwyaaaag. Youw." products: title: "Mauhwaa" released: "Ruhhha"
Scusate la traduzione non proprio corretta, ma non parlo il Wookiee.
Aggiunta dei placeholder
Ora che abbiamo un file YAML per ciascuna lingua, possiamo sostituire il testo cablato nelle pagine con dei placeholder che faranno riferimento alle traduzioni. Rails fornisce un metodo chiamato t
che accetta per argomento la chiave del testo da internazionalizzare. Una volta sostituiti i testi, la nostra pagina indice dovrebbe apparire così:
<% title t('welcome.title') %> <p><%= t 'welcome.paragraph' %></p> <h2><%= t 'products.title' %></h2> <% @products.each do |product| %> <h3> <%= link_to h(product.name), product %> <%= number_to_currency product.price, :unit => "£" %> </h3> <div class="date_released"> <em><%= t 'products.released' %>: <%= product.release_date.strftime("%d/%m/%Y") %></em> </div> <% end %>
Se ricarichiamo ora la pagina, apparirà esattamente come prima, ma al posto di testo statico che c’era prima, stiamo ora vedendo la versione inglese dei nostri testi internazionalizzati.
Cambio lingua
Ora che abbiamo configurato i testi per due lingue, dobbiamo fornire un modo per cambiare la lingua con cui si mostrano le pagine all’utente. Possiamo farlo usando un before_filter nel controller application che chiami un metodo per impostare la lingua.
class ApplicationController < ActionController::Base helper :all protect_from_forgery before_filter :set_user_language private def set_user_language I18n.locale = 'wk' end end
Per provare la traduzione Wookiee, abbiamo cablato il codice i18n del locale relativo al Wookieespeak: ora vediamo il risultato:
La pagina cambia, ma non riusciamo a vedere le traduzioni che ci aspettavamo. La ragione di ciò sta nel fatto che i testi localizzati vengono caricati all’avvio dell’applicazione. Dobbiamo quindi riavviare il server per poter vederli:
Impostazione della lingua dalle preferenze utente
La nostra traduzione ora funziona, ma la lingua da usare è stata cablata nel codice del controller application. Dobbiamo utilizzare la preferenza sulla lingua impostata dall’utente affinchè questi possa vedere il nostro sito nella lingua che preferisce. Dal momento che stiamo utilizzando Restful Authentication, possiamo usare il metodo current_user
per ottenere l’utente loggato e in seguito ottenere anche la sua lingua. Possiamo cambiare il metodo set_user_language
nel controller application per impostare il locale corrente dalla lingua dell’utente, ammesso che questi si sia autenticato:
def set_user_language I18n.locale = current_user.language if logged_in? end
Se guardiamo la pagina come utenti anonimi, l’interfaccia mostrerà la lingua di default, l’inglese, ma se ci autentichiamo come un utente la cui lingua preferita è il Wookiee, allora il sito ci verrà mostrato tradotto in tale lingua:
Due passi finali
Sebbene la maggior parte dei testi sia stata tradotta, ci sono ancora un paio di problemi con la pagina: il messaggio flash che viene mostrato in cima alla pagina non è ancora tradotto correttamente ed i prezzi hanno perso il simbolo della valuta.
Possiamo correggere il problema del messaggio flash aggiungendo un nuovo testo ai nostri due file di internazionalizzazione. Aggiungiamo questa chiave al file en.yml
:
flash: login: "Logged in successfully."
e questa al wk.yml
:
flash: login: "Wohooohaa"
Poi nel controller session dobbiamo aggiornare il codice che imposta il messaggio flash. Nel metodo create
cambieremo la linea che imposta il flash a:
flash[:notice] = t("flash.login")
Si noti che abbiamo accesso al metodo t
dal controller, esattamente come lo avevamo dalla vista. Se dobbiamo invece tradurre qualcosa che è al di fuori di un controller o di una vista, basta tenere presente che il metodo t
è semplicemente uno shortcut per il metodo statico I18n.translate
che ne permette l’utilizzo ovunque.
Possiamo ripristinare il simbolo di valuta mancante usando una delle chiavi riservate usate dal file YAML delle lingue. Ci sono una serie di chiavi per definire cose tipo le date, le ore e la formattazione dei numeri. In cima al file della lingua inglese si trova in link ad un repository Github che contiene un gran numero di file di esempio per svariati linguaggi. Ci inventiamo alcuni simboli e formati per la cultura Wookiee e li aggiungiamo al file relativo:
number: format: precision: 3 separator: '|' delimiter: '-' currency: format: unit: 'ω' precision: 2 format: '%n%u'
Al refresh della pagina, ora vedremo i numeri formattati in modo locale alla lingua, così come la valuta corretta. Se questo fosse realmente un negozio on-line, ovviamente, dovremmo occuparci anche della conversione dei valori delle valute, non solo del simbolo, ma per gli scopi di questo tutorial basta quanto fatto.
Questo episodio ha trattato solo le basi dell’internazionalizzazione di Rails. Ci sono molte altre parti del sito che potrebbero essere localizzate, per esempio il formato delle date e i messaggi di errore delle validazioni. Controllate la documentazione per maggiori dettagli in merito.