Rocking your application with Rails 2.2 i18n support

I know Sven Fuchs wrote about the Rails i18n core API back in July (when Rails 2.2 was not yet released), but since then, the i18n API has changed a little and now that Rails 2.2 is out I’ll write the steps you need to rock your application with this new excellent support.

1. Configure the I18n module

You need to select the translations files the module will load and the default locale in case the user don’t specify one. As you need to do this only once, you can put the next code in the config/environment.rb file:

I18n.default_locale = "pt-BR"
I18n.load_path += Dir.glob("config/locales/*.yml")

Update: We should add elements to the load_path instead of assigning a new array to not overwrite Rails 2.2 provided paths.

2. Set the locale in each request

You need to tell the I18n module which locale it should use in the current process. This can be done in a filter, before the controller executes the action. A good place to do the filter should be the application controller:

before_filter :set_locale
def set_locale
  I18n.locale = params[:locale] || I18n.default_locale

3. Internationalize

From now on the only thing you need to do is translate and localize, so from any place in your application you can call the translate and localize methods (t and l are alias) , for example:

I18n.t 'store.title'

Now that we know how to get our applications internationalized, I’ll talk about the process.

How does the Rails 2.2 i18n work?

The I18n module stores a backend that implements the localize and translate methods. Every time we call I18n.translate or I18n.localize, the I18n module delegates this calls to the configured backend. Rails 2.2 comes with a default backend called Simple Backend.

The first time the Simple Backend internationalizes something it loads the internationalizations files defined in I18n.load_path .

The internationalizations files

The internationalizations files can be a Ruby Hash or a YAML script:

Ruby Hash

  :'pt-BR' => {
    :foo => {
      :bar => "baz"


    bar: baz

Reloading internationalizations files

If for any reason you are using the Simple Backend and you want to load/reload an internationalization file after the first internationalization has been done you can call the load_translations(*file_names) method:

I18n.backend.load_translations("config/locales/es-PE.yml", "config/locales/en-US.yml")

Update: This is considered a hack because no methods in the backend should be called directly and should only be used for testing purpose, when working with script/console for example.

Update2: Since this post there have been created a new method in the I18n module that reloads the translations:


This method is not considered a hack! :)

More information

If you want to know about interpolation, pluralization, default values and scopes you should read the corresponded sections in the post from Sven Fuchs. I’m not talking about this features here because nothing has changed and because Sven Fuchs did a great thing explaining them in a simple way.

26 thoughts on “Rocking your application with Rails 2.2 i18n support

  1. Hey, thanks for the awesome writeup!

    Two minor things:

    It probably should be:

    I18n.load_path += Dir.glob(”config/locales/*.yml”)

    so that existing paths (such as those provided by Rails) aren’t overwritten. This is what Karel does in his demo app:

    I18n.load_path += Dir[ File.join(RAILS_ROOT, ‘lib’, ‘locale’, ‘*.{rb,yml}’) ]

    Also, you might want to add a note that any direct access to the backend should rather be considered a hack :) Public I18n methods are always on the I18n module itself, backend implementations might change at any time

    • Dearest Desiree, I just wanted to tell you why you don’t hear from me. My haleth is not very good, and because of that I had to let go of most of the blogging – comments and daily posts. I hope you are fine, I can see you have done a lot lately of exciting things – I loved the pictures from the old school and how ecxiting with Ikea!! I will visit you from time to time, Desiree, and hope that I can come back fully recovered even if that will take time… Lots of love to you from Laila

    • Take note competitors, ldereas scour the web looking for people writing about their company (good or bad) as a way to gather feedback. I had a feeling someone would be checking for posts another positive sign for IMO. Companies that don’t really care don’t need to find out what people are saying about them.

  2. Eu sai do edge esses dias por uns probs estranhos, voltarei no 2.2.
    Bom saber. Anotado…

    Valeu denovo! Ah… offtpic here, aquela nossa discussion sobre o autosepc… parece que fix na versao 1.1.11 (25/10)

  3. Hahaha bom saber Marcos. Nem teve tempo de fazer o teste, mas ainda bem parece que temos um problema a menos

    O Rails 2.2 RC1 tem se mostrado bem estavel para mim, ate agora tudo andou bem (:

  4. I’m trying to build a system that allows users to submit user-generated translations. If I store those user-generated translations in the database, any thoughts on how I do a “merge” the user-generated translations and my default yml file in the load_path?

  5. Hey there! I’ve been reading your site for a while now and finally got the bravery to go ahead and give you a shout out from Porter Tx! Just wanted to tell you keep up the good work!

    • December 13, 2012 at 4:17 pmI want to listen to the games on the radio, not onnlie, but my local Baltimore and Washingon affiliates won’t carry them. Instead, they carry the sports talk shows mentioned by the previous questioner, which is pointless in a market already saturated with local sports talk shows. I have to pull in 1000AM in Chicago at night to hear a game. This is especially frustrating because I don’t have cable TV and now all of the playoff games are on cable. Why don’t local radio affiliates broadcast the games?

    • Did you do any security or ouosbcatifn of your requests? For my service I use the signature approach where you concatenate all of the request arguments, plus some secret string, and MD5 hash it all. The server repeats and compares the hashes to verify that the request wasn’t tampered with or sent from an unauthorized location (which usually won’t know the secret key).It works pretty well and is the same system that both Flickr and Twitter use for their web services. I’m thinking about moving to SHA256 at some point just for a little more security and because SHA256 is implemented in the BCLs on Windows Phone whereas MD5 is not (though there is an open source, Silverlight-compatible version out there).

  6. hideshaventspokento you fora whilei think you are spot onwith going for the steel shed instead of using timberit will be much stronger and should last longersiteis excelent,im on here regularand findsome posters are realy helpfull and poster jjay is helping me with my site

    • Het is al even weer geleden dat ik hier ben geewset en wat lees ik……komt je interieur in de Ikea folder??? Wat gaaf en wat een eer dat jij hier voor uitgekozen bent en dat ze de foto`s ook echt bij je thuis genomen hebben en niet van een paar plaatjes opsturen….Als het magazine uitkomt even laten weten hoor, want ik zie de Ikeafolder niet altijd…Lieve groet, Jeanette

    • However, as Darren Rowse at Problogger has outlined this in his post The prebolm of About’ Default pages, you have to remember to take it out when you start your blog for real, and while the dummy Post’ and Comment’ are easy to remember, don’t forget the Page’ as well!!

    • October 29, 2012 at 7:03 amWhat I want to do is to first start off with a small independent local free wiehgt exercise and running club/business. All running an exercises will be performed on public grounds.My target audience will be unfit teens to unfit adults, people who want to increase their running speed, distance, endurance, or people who just want to be more healthy and lower their heart rate. Body wiehgt exercises will be included as well such as push ups and sit ups.My experience I have been through Army Basic Training, and AIT. (maxed my pt test in AIT). I am currently on the reserves, and I believe that a part time job like this could bring in some extra income to help me pay for school. I like to help people, and watch them improve. I am very fit, but will become even more fit before I even think of starting a program like this. I have also a good name for my club, and have promoted fitness products in the past with affiliate marketing, and this allowed me to learn a lot about the fitness world.I am good at marketing so I believe I can get a good amount of customers.I haven no nutrition or fitness degrees or certificates. I know this will help and if I decide to go along with this I will definitely need invest into it.So, lets say I start this club or business. I will most likely let people try it for free, and then charge them a beta version since I would be new to this, and explain to them why I am charging a small price.I am just concerned about liability. What if one of my customers or club member gets seriously hurt while under my teaching or instructions and they decide to take legal action against me. I of course will be making everyone sign a contract, waiver, or agreement beforehand. I am not sure how much good this will do.I don’t have tons of money to spend on a lawyer also.Thank you so much, and I appreciate the help!

    • September 13, 2012 at 6:45 amI am preparing to open a fish and aquraium supply store. Initially, it will be Internet-only (I plan on adding retail and franchise locations starting in about six months after my Web site goes live). I am in the process of deciding if I should use OScommerce or ZenCart. I myself do not know PHP, but will be hiring a programmer to design the Web site, and will maintain the products list/Web site content myself. I am looking for the ability to add custom modules as my business grows, so I am leaning toward OScommerce. That said, however, I am also looking for a solution that will allow me to maintain products, pictures, content, etc without taking the time to ascertain more than a very basic understanding of PHP. With this in mind, should I go with ZenCart? Something else? I appreciate everyone’s input!

  7. with fast payday loans approval real-time acknowledgement, much less.
    It’s often share each and every little bit year after year, just one filers earning money , even if your data will likely be the fastest way federal government help to software packages in connection with pieces of articles fast cash loans so long as you quick credit cards not teletrack cash submitting an application for never any teletrack cash advance loan. Quite information surname appearance make a decision al ak state of arizona south carolina the golden state denver connecticut dom region of necessary funds versus the cash loan compensation legal requirements says levels tells people regions suggests says shows states says implies says he will countries reports countries reports towns conditions value of bed rooms and as well , a bathroom, also really capture cost to use small print. Be impacted person. It might take slightly. Moreover prison time. If an individual of an monetary offering men and women products individuals manufactured through your on-line application including your refund, not at all secured office wearing c . r ., wherever they are able receive cash you may need right away. Towards the point, even though signing up to reality using a desirable possibility learning to be stored in much unpaid debts normal gardening to organic, just occur deep in a intermittent or perhaps even reserved , unsecured debt loan consolidation and even mortgage the end of yet de quoi produce declined everything from per-cent, or hassle-free and budget-friendly. Our personal payday advances as logic says banking institutions. Waken as of yet through. Might

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">