i18n-flagsUn'applicazione web che si rispetti deve potersi adattare alla lingua di colui che ne usufruisce. Dalla versione 2.2 di Ruby On Rails rendere un'applicazione multilingua è diventato estremamente semplice grazie al framework I18n. In pratica tutte le stringhe che in qualche modo verranno visualizzate nelle viste sono sostituite da appositi placeholder che Rails, a runtime, carica in maniera differente a seconda della localizzazione dell'utente.

Il primo passo è definire la localizzazione di default in conf/environment.rb:

config.i18n.default_locale = :it

Le stringhe di localizzazione vengono caricate da appositi file yaml nella cartella conf/locales/, quindi, utilizzando la lingua italiana, dobbiamo creare il file conf/locales/it.yml in questo modo:

it:
    hello_world: "Ciao Mondo!"

e analogamente il file con le traduzioni per ogni lingua che vogliamo.

Adesso le stringhe che devono essere localizzate sono fondamentalmente di due tipi:

  1. Le stringhe nelle viste
  2. Le stringhe che vengono visualizzate nelle viste ma sono generate al di fuori di esse, ad esempio i flash nei controller

Ecco come localizzare le stringhe nelle viste:

<%=t "hello_world" %>

Ovvero si utilizza un nuovo tag di stampa il cui contenuto è il placeholder che dovrà essere sostituito. Se invece ci troviamo in una situazione del genere:

<%= link_to "Hello, World!", "/somewhere" %>

la soluzione è quella di ricorrere direttamente alla classe I18n:

<%= link_to I18n.t('hello_world'), "/somewhere" %>

In questo stesso modo si possono localizzare tutte le stringhe al di fuori delle viste, ovvero il caso 2 nella lista precedente:

class ExampleController < ApplicationController
  def index
    flash[:notice] = I18n.t('hello_world')
  end
end

A questo punto manca solo un modo per modificare la localizzazione al volo.
La variabile che contiene la localizzazione attiva è I18n.locale ed è quindi necessario modificarla quando si vuole cambiare localizzazione.
Un esempio per farlo è utilizzare un apposito metodo in app/controllers/application_controller.rb:

class ApplicationController < ActionController::Base
  before_filter :set_locale
  private
    def set_locale
      I18n.locale = params[:locale] unless params[:locale].nil?
    end
end

In questo modo basta un qualsiasi link col parametro locale (ad esempio /example/index?locale=en) per modificare la lingua.

Un difetto di questa procedura è che ogni link deve contenere il parametro locale, altrimenti viene caricata la lingua di default. Una soluzione può essere quella di mettere in sessione l'ultima lingua indicata e quindi caricare la lingua dalla sessione ad ogni pagina. Il metodo può inoltre essere modificato per verificare che la localizzazione effettivamente esista.

def set_locale
  # Set session[:locale] if params[:locale] exists and is an available localization
  unless params[:locale].nil?
    session[:locale] = params[:locale] if I18n.available_locales.include? params[:locale].to_sym
  end
  # Set the locale if previously set in the session, otherwise use the default one
  I18n.locale = session[:locale] unless session[:locale].nil?
end

Una bottoniera carina per gestire il cambio di lingua può essere fatta inserendo nel layout questo codice:

<div id="flags">
   <a href="?locale=it"<%= " class=\"active\"" if I18n.locale.to_s == "it"%>><img src="/images/flags/it_IT.gif" alt="Italiano" title="Italiano"></a>
   <a href="?locale=en"<%= " class=\"active\"" if I18n.locale.to_s == "en"%>><img src="/images/flags/en_EN.gif" alt="English" title="English"></a>
 </div>

nel foglio di stile questo codice:

div#flags {
 margin: 10px;
}
div#flags a img {
 padding: 4px;
}
div#flags a.active img{
 background-image: url('/images/active_flag.png');
 background-repeat: no-repeat;
 background-position: center center;
}

ed utilizzando queste immagini: active_flagen_ENit_IT

Il risultato è questo, con la lingua attiva contornata da un alone celeste:

rails_localization_flags

È sufficiente cliccare su una bandiera per attivare una diversa lingua. Su Deviant Art trovate decine di flags pack, sbizzarritevi :)

blog comments powered by Disqus