UPDATE: you don’t need this code, because starting from the 2.2 version of Rails, localization support is built-in.
Localization for Active Record error messages
Today i had to answer to one of the questions every non-english Rails developer
stumbles upon now or after.. how to localize AR error messages for pleasant
appearance to a non-english customer ;).
First off, thanks to defunkt’s excellent gibberish
plugin and to the way AR validation errors are exposed, the task was
accomplished in an easy and clean manner, without messing too much with AR’s
internals.
I started by translating every default AR error message, with this translation
file located 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 validationsar_greater_zero: "deve essere maggiore di zero"
The first one simply sets Italian (:it) as the default language, the inject
builds a new error_messages hash using Gibberish to translate the default ones.
I named every AR error key in my translation file with an “ar_” prefix, in
order to avoid possible future key clashes. Finally, AR array is overwritten
with the new one freshly built.
This solution assumes that the application will show only in a single language,
if you need localized error messages in different language you should put this
code in some around_filter, like Gibberish documentation suggests.
OK, messages are translated, but what about field names? I used english field
names in my tables, how about translating them as well? First, we need the
actual translations 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"
And then a customized helper that our view will call, loosely based on the
default error_messages_for Rails helper:
# error messages localization# uses gibberish.deffoo_object_error_messagesreturn''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
Here, easily, every field name is substituted by its translated counterpart,
and a div is built with the plain vanilla class and id used by Rails’
[code]scaffold.css[/code], so that I won’t have to write a single line of CSS.
In your view: <%= foo_object_error_messages %>
This helper could be of course improved, but I’m a bit lazy right now.
Five minutes ago, I overwritten the super-shining-new CSS stylesheet that
implements the current color scheme, because i wanted to restore the original
one and put it in a new theme for this site, so that people who enjoyed the old
theme could continue to use it. But, as the most kiddiest system administrator,
i uncompressed the original files from the backup archive OVER the current
ones..
Safari to the rescue! Every cached item by safari is stored into a SQlite3
database located in ~/Library/Caches/com.apple.Safari, let’s inspect how it
is structured:
Wow. Impressive. That’s why i love Apple products, because they are so well
structured that you can freely inspect them and use them and their resources
for every unplanned task you could have to complete.. even to fix your own
mistakes ;). And it’s also intriguing, because you have to scratch your own
itch and find the solution while exploring a beautifully constructed software
product.
To make a long story short, every cached URL is stored into the request_key
field of the cfurl_cache_response table, while in the receiver_data field
of the cfurl_cache_blob_data there is the actual cached data. Now we can look
for the overwritten bbs theme CSS stylesheet:
sqlite> select entry_ID, request_key from cfurl_cache_response
...> where request_key like '%bbs/style.css';
??1950??|http://sindro.me/sites/all/themes/bbs/style.css
Now, let’s search in the blob_data table the entry with ID 1950:
sqlite> select receiver_data from cfurl_cache_blob_data
...> where entry_ID = 1950;
/**
* Themetastic, for Drupal 5.0
* Stefan Nagtegaal, iStyledThis [dot] nl
* Steven Wittens, acko [dot] net`
*
* If you use a customized color scheme, you must regenerate it after
* modifying this file.
[......rest of the stylesheet removed.....]
YAY! Found it! A quick cut&paste.. and the lost theme is back! :D
Add /usr/local/include to BASECFLAGS in Makefile (autocrap sucks).
Patch Modules/ctypes/_ctypes_test.c by putting an #ifdef HAVE_LONG_LONG around functions that use PY_LONG_LONG (hints: lines 384 and 318).
Patch Objects/longobject.c and on line 817 put the IS_LITTLE_ENDIAN macro before the #ifdef HAVE_LONG_LONG block, and put _PyLong_FromSsize_t and _PyLong_FromSize_t after the HAVE_LONG_LONG block.