sindro.me

feeling bold
on the internet

info 🇬🇧🇮🇹

Active Gibberish

- 3 min di lettura

AGGIORNAMENTO: non ti serve questo codice, perché a partire dalla versione 2.2 di Rails il supporto alla localizzazione è integrato.

Localizzazione dei messaggi di errore di Active Record

Oggi ho dovuto rispondere a una delle domande su cui ogni sviluppatore Rails non anglofono prima o poi inciampa… come localizzare i messaggi di errore di AR per mostrarli in modo decente a un cliente che non parla inglese ;).

Prima di tutto, grazie all’eccellente plugin gibberish di defunkt e al modo in cui gli errori di validazione di AR sono esposti, il compito è stato portato a termine in modo semplice e pulito, senza mettere troppo le mani negli internals di AR.

Ho cominciato traducendo ogni messaggio di errore predefinito di AR, con questo file di traduzione in lang/it.yml:

# Active Record errors
#
ar_accepted:     "deve essere accettato" 
ar_not_a_number: "non è un numero" 
ar_blank:        "è un campo obbligatorio" 
ar_empty:        "è un campo obbligatorio" 
ar_inclusion:    "non è nella lista dei valori validi" 
ar_too_long:     "è troppo lungo (massimo %d caratteri)" 
ar_exclusion:    "è riservato" 
ar_too_short:    "è troppo corto (minimo %d caratteri)" 
ar_invalid:      "non è valido" 
ar_wrong_length: "è errato, dovrebbe essere di %d caratteri" 
ar_confirmation: "non corrisponde" 
ar_taken:        "esiste già" 
# This one is not a default key, but I use it in my validations
ar_greater_zero: "deve essere maggiore di zero" 

e quattro righe in config/environment.rb:

Gibberish.current_language = :it
ActiveRecord::Errors.default_error_messages =
  ActiveRecord::Errors.default_error_messages.inject({}) {|h, (key, string)|
    h.update(key => string["ar_#{key}".intern]) # <em>Gibberish magic</em>
}

La prima riga imposta semplicemente l’italiano (:it) come lingua predefinita, l’inject costruisce un nuovo hash error_messages usando Gibberish per tradurre quelli predefiniti. Ho nominato ogni chiave di errore AR nel mio file di traduzione con il prefisso “ar_”, per evitare possibili conflitti futuri di chiavi. Infine, l’array di AR viene sovrascritto con quello appena costruito.

Questa soluzione presuppone che l’applicazione venga mostrata in una sola lingua; se hai bisogno di messaggi di errore localizzati in lingue diverse, dovresti mettere questo codice in qualche around_filter, come suggerisce la documentazione di Gibberish.

OK, i messaggi sono tradotti, ma i nomi dei campi? Ho usato nomi di campo in inglese nelle mie tabelle, come tradurre anche quelli? Prima ci servono le traduzioni effettive in lang/it.yml:

# Field names
#
fld_multiplier:  "La dimensione" 
fld_service_id:  "Il servizio" 
fld_customer_id: "Il contraente" 
fld_address_id:  "L'indirizzo" 
fld_user_id:     "L'utente" 
fld_city_id:     "La città" 
fld_state_id:    "La provincia" 
fld_address:     "L'indirizzo" 
fld_terms_of_service: "Il testo di informativa sulla privacy" 

E poi un helper personalizzato che la nostra view chiamerà, liberamente basato sull’helper Rails predefinito error_messages_for:

  # error messages localization
  # uses gibberish.
  def foo_object_error_messages
    return '' if @foo_object.errors.count.zero?
    header_message = "Si prega di correggere i seguenti errori:" 
    error_messages = @foo_objects.errors.map do |field, err|
      field = field["fld_#{field}".intern] # [i]Gibberish magic[/i]
      content_tag(:li, "#{field} #{err}")
    end 
    content_tag(:div,
      content_tag(:h2, header_message) <<
        content_tag(:ul, error_messages),
      :class => 'errorExplanation',
      :id    => 'errorExplanation'
    )   
  end 

Qui, semplicemente, ogni nome di campo viene sostituito dalla sua controparte tradotta, e viene costruito un div con le classi e gli id standard usati dal [code]scaffold.css[/code] di Rails, così non devo scrivere neanche una riga di CSS.

Nella tua view: <%= foo_object_error_messages %>

Questo helper potrebbe sicuramente essere migliorato, ma al momento sono un po’ pigro.

Divertitevi! :D