In Internationalization (I18n) API in Ruby on Rails 3 (Part I) and Internationalization (I18n) API in Ruby on Rails 3 (Part II) we already covered a lot of the Rails I18n functionality. In part III, we will now look at some more advanced features of I18n.
Using Different backend with I18n
The I18n ruby gem comes with backend support for resource files (more specifically .yml files). Additionally, it also provides simple approach to exchange the backend implementation using different gem/plugin depending on your requirements. Let’s examine an example where all translations are stored within database.
Using Database backend for Ruby I18n API
You can easily use your database for storing all the translations with the help of i18n_backend_database (https://github.com/dylanz/i18n_backend_database) plugin. This plugin will store all your translations in the database instead of YAML files and provides a caching mechanism, so that the database doesn't get hit for every translation. When you tag items using i18n.t() within the code base, all of untranslated items will be noted as well as added into the database. You can translate untranslated textual content through an administrator panel provided by plugin.
Update 2011-02-01
Please note that this plugin is not yet ready for Rails 3 (see comments). Here are the steps to use this plugin for Rails 2.x:
[gist id=801603]
Add this lines in config/initializers/i18n.rb
[gist id=801606]
In config/routes.rb register admin panel routes
[gist id=801610]
Now, rails application can translate all the code from the database. All non-user generated text provided by the application needs to be wrapped in a call to I18n.t().
[gist id=801637]
Interpolation is handled by passing in key/value pairs as a value to an interpolation tag ( {{ }} ).
[gist id=801638]
Translating Routes with translate_routes Gem
The Ruby gem translate_routes helps you to translate URLs to any number of different languages, even for an already working application. This gem works with Rails 3.x. and also with other Rails versions like 2.1.x, 2.2.x and 2.3.x. The Ruby gem translate_routes is working good with all type of routing definitions, which includes RESTful as well as named routes. You don't have to change your existing routing code, helpers, and so on; links work as expected - even in your tests.
Add translate_routes to your Gemfile:
[gist id=801612]
And let bundle do the rest: bundle install
1) Let's say you have this in your routes.rb file:
[gist id=801614]
You can see the available routes with the 'rake routes' task:
contact /contact(.:format) {:controller=>"contact", :action=>"index"}
2) Now write your translations in a standard YAML file (e.g: in /config/i18n-routes.yml), including all the locales and their translations pairs:
[gist id=801617]
3) Append this line in your routes.rb file to activate the translations specifying the path of the translations file:
[gist id=801618]
4) Execute rake routes to see the new routes:
contact_es /es/contacto(.:format) {:controller=>"contact", :action=>"index"} contact_en /contact(.:format) {:controller=>"contact", :action=>"index"}
5) Include this filter in your ApplicationController:
[gist id=801619]
Now your application recognizes the different routes and sets the I18n.locale value in your controllers. But what about the routes generation? As you can see in the previous rake routes output, the contact_es_es_path and contact_en_us_path routing helpers have been generated and are available in your controllers and views. Additionally, a contact_path helper has been generated, which generates the routes according to the current request's locale.
This means that if you use named routes, you don't need to modify your application links because the routing helpers are automatically adapted to the current locale.
6) What about tests?
Of course, functional and integration testing involves some requests. The plugin includes some code to add a default locale parameter so they can remain untouched. Append it to your test_helper and it will be applied.
You can find additional information in the translate_routes' wiki.
Globalize2 - Alternatives for Ruby I18n Gem
The Ruby gem Globalize2 was very popular in Rails community because it provides full-fledged internationalization solutions for Ruby on Rails application. You can use most of the features/tools independently and also you can combine them with other libraries or plugins.
The Feature/Tools for this gem are listed below.
- Model translations – This functionality transparently translates ActiveRecord data
- Locale LoadPath – This gem load translation data from standard locations enforcing conventions that suite your needs
- Locale Fallbacks – This feature make sure your translation lookups fall back transparently through a path of alternative locales that make sense for any given locale in your application
- Translation value objects – You can access useful meta data information on the translations returned from your backend and/or translated models
Conclusion
The I18n API comes with plenty of features and yet hides the complexity behind a simple to use API. With this gem, a Ruby on Rails application has a great built-in support for multiple languages. As the diversity of users is growing and more and more users speak different languages, a good localization and internationalizationsupport is necessary for every serious Web Framework. If your application has a more specific need, have a look at the various plugins and extensions available. Rails has also a great documentation, and of course there is an Internationalization section, I18n Wiki.