Ruby on Rails plugin: Localize your Rails app
Recently I’ve been working on a plugin for Ruby on Rails that help me out when creating new Rails applications in Danish. Previously, when we’ve created Danish prototypes for our customers all the default Rails error messages were still written in English.
I generalized it for use with any language, and currently (with the help from contributors) it’s now available for download on rubyforge.
I gave a short plugin demo at our recent Copenhagen Rails Meetup. Olle and Jakob already wrote briefly about it. You can read more (and vote) on agilewebdevelopment page Localization Simplified.
Currently supported languages:
- Danish
- Dutch (thanks Jeroen Houben)
- German
- Spanish (thanks Luis Villa)
- Swedish (thanks Olle Jonsson)
- Swedish Chef
- Pirate Talk (thanks Tobias Michaelsen)
The main reason why I wanted to support Swedish chef and Pirate talk is that I want to remind myself to have fun while coding. And of course it’s a plus that International Talk like a Pirate day is coming up at Sept. 19, arrrh!
What it does
This plugin modifies the following most used helpers for Rails
- Localized errors and error headings
- Localized monthnames on date_select etc. (changing the order of Y-M-D, where Rails allows)
- Localized distance_of_time_in_words
- Localized to_currency (but not changing the order of unit/currency)
- Simple pluralization also available in the lang-file (but currently only used for pluralizing “error”=>”errors” in local language)
- Uses standard Rails methods. In this way, there is no tedious rewrite of localization functions in your view files
There are some FIXME’s in the code and any help on the plugin is appreciated.
As I’ve written in the Rails Core group, this plugin does some work that I hope will be worked into the Rails framework for easier future internationalization.
An example: distance_of_time_in_words() are hardcoded and translated into at least 4 different l10n plugins. If it changes in Rails Core, ALL the plugins must be fixed to ensure that the new code is copied to the plugins.
Seen from the perspective of a localized app, there should be as few dependencies as possible, so making hooks available for localization is preferred. In the example above, the texts should be available as a variable (like the error messages in ActiveRecord).
This would be an ideal solution to some of the most important i18n related issues, and I’d like to know the view of the community on this point.
From my post “i18n-friendly, plugable Rails core” in the Ruby on Rails Core list.
It’s my hope that the Rails Core team will acknowledge that it should be easier to localize your application. (Today, many text strings and date/time/currency formats are hard coded and difficult to overwrite).
Technorati Tags: ruby on rails, rails plugin, simple localization, l10n, i18n, internationalization, danish, swedish, dutch, spanish, german, swedish chef, pirate talk, pirate day, translation
August 24th, 2006 at 10:41 (GMT-1)
[…] Update: Jesper shows the plugin in action at his website. Take a look! […]
August 24th, 2006 at 12:06 (GMT-1)
You have probably all heard about the new keyboard layout designed specifically for pirates. It’s all R keys.
August 24th, 2006 at 13:24 (GMT-1)
Cool stuff ! Only thing which i see as missing and really needed is to translate also column names, as I can see from example above “First Name” is not translated – too bad… Any plans to support that?
August 24th, 2006 at 13:30 (GMT-1)
I mean “Last name” of course… ;o)
August 24th, 2006 at 16:25 (GMT-1)
Nice stuff.
How you compare your plugin with Ruby-GetText ?
I ask ’cause, currently I’m localizating rubycorner.com using Ruby-GetText.
August 25th, 2006 at 14:21 (GMT-1)
MIro: No plans on translating column names or model names. I’m afraid that this will bloat the code more and give difficult dependencies to Rails code. Some of the other l10n/i18n plugins support it, but it usually requires that you add plugin dependent methods in your views.
If you build a local website using english model and attribute names, one workaround could be to translate model to local language (although I know this is considered bad code style in most cases).
I have no plans right now for adding translation of model names and attributes, but if somebody can show me how to do it without adding code in views and without giving too many dependencies, I might consider it.
Edgar: For a comparison of the different localization plugins, see http://wiki.rubyonrails.org/rails/pages/InternationalizationComparison
August 25th, 2006 at 16:23 (GMT-1)
Polish your Rails…
…
September 4th, 2006 at 05:41 (GMT-1)
It’s not enough for L10n to support “one-language application” only.
If you merge your plugin into Rails Core, I hope it’ll support multi-language like other L10n plugins.
Anyway, if your plugin works with Gettext, I’ll try it.
September 7th, 2006 at 10:32 (GMT-1)
jesper,
I like the narrow focus of this plugin (one language per app) – but I really miss being able to reorder date selects. I mean the whole purpose of this plugin is to quickly create a localized form. Would you consider supporting it, I’ll be happy to take a look and see if it can be done with too much hassle.
Jeroen
September 7th, 2006 at 11:12 (GMT-1)
Jeroen,
The newest version already supports reording of date_selects but not datetime_selects (not implemented in Rails). I started a discussion on the Rails Core mailinglist.
According to Bob Silva, there are patches for datetime_select, so you could start using it right away.
Reordering of date_selects is starting in version 0.6 of the LocalisationSimplified plugin.
September 7th, 2006 at 11:25 (GMT-1)
Info: Just released version 0.6.1 with few bugfixes and more new languages.
http://rubyforge.org/frs/?group_id=2074&release_id=6836
September 7th, 2006 at 11:35 (GMT-1)
Hmm I just updated the plugin but this still doesn’t work:
select_date(Date.today, {:order => [:day, :month, :year]})
Am I overlooking something?
September 7th, 2006 at 19:59 (GMT-1)
Plugin doesn’t work (yet) for select_date() but only for date_select and datetime_select.
September 8th, 2006 at 09:21 (GMT-1)
This should fix select_date to use the correct ordering too.
def select_date(date = Date.today, options = {})
order = LocalizationSimplified::DateHelper::DateSelectOrder[:order]
send(“select_#{order[0]}”.to_sym, date, options) +
send(“select_#{order[1]}”.to_sym, date, options) +
send(“select_#{order[2]}”.to_sym, date, options)
end
Jeroen
September 11th, 2006 at 22:26 (GMT-1)
[…] As I pointed out while working on my own Localization plugin, there are plenty of loose ends in Rails that could make localization much easier with Rails. […]
September 27th, 2006 at 21:34 (GMT-1)
Nice plugin – small, easy, exactly what I was looking for.
I had to remove the UTF8 part though, because it didn’t play with .rjs templates (i.e. remote javascript) for what reason ever.
For the column names: For my needs it was enough to overwrite ActiveRecord::Base.attribute_human_name (the class method) – this works nice for me in 1.1.6 and Edge.
Last but not least, the german translation isn’t quite perfect ;) – but that’s ok, you have pirate’s talk. The need for different flections? and articles depending on the context are a problem which seems to be a bit harder to solve within a simple solution.
September 27th, 2006 at 22:07 (GMT-1)
Benedikt: Thanks for your thoughts and experiments on this. I would love if you’d send me the code examples you ended up using. I will add it to the plugin if it can be of general benefit.
I would be glad if you modify the german translation: I did some of that, so that explains the quality :) Please send me an updated copy, so that I can give you credit and include in next release
I have not tried it out yet with RJS, so I’m really glad you noticed. Please let me know what you did and what response you got. I hope that maybe someone else can contribute with a solution.
February 21st, 2007 at 15:44 (GMT-1)
I even ran into the .rjs problem. And if the line with the modified header (localization_simplified.rb, line 256) is commented out everything works fine for me. Do you know what kind of side effects could be caused by doing that?
By the way: Great work!! :)
February 21st, 2007 at 15:58 (GMT-1)
BT: There is no line 256 in the current version (0.8). Which version are you using?
I suggest you upgrade to version 0.8 (but beware that it requires Rails 1.2)
In Rails 1.2, the content header is automatically set, and thus the problem that you run into is solved, as long as the line is commented out.
February 21st, 2007 at 17:01 (GMT-1)
Of course you’re right I forgot to upgrade, sorry! Now everything works fine!
Thanks a lot
BT
August 16th, 2007 at 16:46 (GMT-1)
Maybe it meight be of interest. I used the human_attribute_override plugin for translating fieldnames in error messages. And I have “translated object name” %> in my views.
Its not the best solution, but it works very well with this plugin.
I also made a modification on how :error_translation and :error_header are used. In German the plural of error (Fehler) is the same as the singular, but instad i nead to pluralize the second word in :error_header.
My dirty workaround:
(error_messages_for)
…
messages = ActiveRecord:: Errors.default_error_messages
if(count>1 && messages[:error_header_plural]!=nil)
errorheader=messages[:error_header_plural]
else
errorheader=messages[:error_header]
end
if(count>1 && messages[:error_translation_plural]!=nil)
errorcount=format(“%d “+messages[:error_translation_plural],count)
else
errorcount=pluralize(count, messages[:error_translation])
end
header_message = format( errorheader,
errorcount,
(options[:object_name] ||
params.first).to_s.gsub(“_”, ” “))
error_messages = objects.map {|object| object.errors.full_messages.map {|msg| content_tag(:li, msg) } }
…
With :error_header_plural and :error_translation_plural added to the error messages. This produces “1 Fehler verhinderte…” or “2 Fehler verhinderten…”
PS: As you see, I’m new to rails and ruby. Sorry
March 20th, 2008 at 00:17 (GMT-1)
Hello,
I get this Error:
activesupport-2.0.2/lib/active_support/dependencies.rb:478:in `const_missing’: uninitialized constant Rails::Plugin::L10N_LANG (NameError)
But the var is set in the environment.rb and/ or init.rb. Is there special dependency to a native library or gem? Or whats going wrong?
Thanks
March 28th, 2008 at 00:59 (GMT-1)
@histidin
I have reproduced your bug by adding the plugin and doing nothing else
But the bug dissapears the moment I add this line as the first line in my /config/environment.rb
L10N_LANG = :da
Unfortunately my time is limited right now to look more into it. But I wonder what happens at the line in /vendor/plugins/l10n-simplified/init.rb:
L10N_LANG ||= :da
As the above line should act as a fallback for the plugin. Please let me know anything you find out.
/Jesper
August 27th, 2008 at 03:07 (GMT-1)
We’ve developed a Web 2.0 tool managing translations. It has very good Rails support – allows using Ruby GetText and YML format for your translations.
Please check it out.
December 18th, 2010 at 04:17 (GMT-1)
I used the human_attribute_override plugin for translating fieldnames in error messages. And I have “translated object name” %> in my views.