Recent posts:
The Wordchuck Blog.
Shelly Roche is a Ruby on Rails engineer and founder of Wordchuck. She usually blogs about Ruby, Rails 3, woodchucks, i18n, l10n, startup life or whatever has her fired up on any given day. Yes, she is available for i18n consulting & training. Find her or by . |
How to: Internationalize in Rails 3
What is Internationalization?
If you want to offer your site in more than one language, you need to go through a process called internationalization (i18n) and localization (l10n).
The internationalization process involves abstracting your site’s content strings, dates and currencies from your application and replacing each abstracted piece of content with a placeholder.
The localization process involves translating your content and providing other locale-specific information, like date and currency formats.
Internationalization in Rails 3:
In Rails 3, all dependencies for Internationalization (i18n) are already included, so let’s take a look at the three steps required to get up and running using I18n’s default Simple backend (more on that in another post):
Step 1: Abstract your content
Each piece of text we want to translate will need to be copied into a new file, called a locale file. Locale files can be .yml or .rb format, and will be created in our config/locales directory. Our base locale is the default language for our site, in my case, English. My base locale file is therefore called en.rb (config/locales/en.rb).
In this example, I’m copying the “Welcome to my site!” string from my view:
"content">Welcome to my site!</h2>
You are going to like it here.<
/p> </div>
{ :en => { :welcome => { :page_title => "Welcome to my site!" } } }
Step 2: Insert placeholders
As we abstract each piece of content, we need to replace it with a placeholder that will perform the lookup to display the properly translated content to our users. Continuing with the example from above, we're going to replace the “Welcome to my site!” text in our view with our call to I18n’s translate method, passing in the section and key we defined in our locale file to help identify the correct piece of content:
"content"><%= t(:page_title, :scope => :welcome) -%>
>You are going to like it here.
</div>
Step 3: Set the locale
The final step is to set up your application to pass the locale, so the i18n placeholders know which translations to display.
The default locale is updated on every request within a before_filter set in the ApplicationController:
before_filter :set_locale def set_locale I18n.locale = params[:locale] if params.include?('locale') end
The idea here is to set the locale on every route automatically, based on what locale is set for the current request:
def default_url_options(options = {}) options.merge!({ :locale => I18n.locale }) end
In order for this to work, we need to wrap every applicable route within a :locale scope to ensure that the locale is included within any named routes.
Your routes file will look something like this:
scope ':locale' do resources :buckets, :only => [ :index ] resources :items, :only => [ :index, :show, :edit, :update ] end
This way, we don’t have to specify the locale manually when we call a named route method. It all happens automatically for us.
Of course, you do not have to store the locale in the URL if you do want to. It can also be stored in browser's session[], or as a data item within the user's database profile. But placing the desired locale in the URL ensures that bookmarks or shared links always point to the content as the user was looking at it.
YAY - we've made it through a simple i18n setup and ready for our next step: localization!
Additional Resources:
If you'd like to play around with a fully-featured Rails 3 i18n implementation, check out our demo app here. The source code is available on github, so you can see exactly how everything works.
The official Rails i18n API documentation is excellent, and packed with all sorts of additional details and options for doing more complex implementations of internationalization.