Internationalization (I18n) in Rails 2.2

Rails 2.2 was released late November, about two weeks ago. Of all the new features, one of the most prominent is the out-of-the-box implementation of internationalization (i18n, because it has 18 letters between I and N) in the new Rails 2.2 generated application (using the rails command).

Before we dive into the implementation, we’re going to discuss a bit of the evolution of this solution.

In the Good Old Days (possibly before the Internet was widespread in usage), applications hard-coded their strings. So if you had a login form/box/control/screen/something, you’d have something like:


Login:
Password:

What, then, happens if you want to translate your application into another language like French? You could always hard-code the new values, and maintain a second version; but that’s expensive to maintain.

Then an idea emerged–how about storing the strings in a file somewhere, and using some sort of class to get the strings?

So you might have a class like this:


class LanguagePack
def get_string(string_key)
# open up a text file specified in LanguageManager.language
# look for the line with string_key
# return the actual text
end
end

This class contains the strings. Accompanying this would be the strings file, like so:


# en.txt
password = Password:
login = Login:

To obtain strings, you ask the LanguageManager, like so:


class LanguageManager

attr_accessor :language

def get_string(key)
LanguagePack.get_string(key)
end
end

So you can do things like this:


LanguageManager.get_string("password") # => "Password: "
LanguageManager.language = "fr" # use French, search fr.txt
LanguageManager.get_string("password") # => "Mot de Passe: "

As you can see, changing languages is easy–just call LanguageManager.language = fr", for example, to use French. C’est bon!

Your form would then be:


<%= LanguageManager.get_string(login) %>
<%= LanguageManager.get_string(password) %>

And this is precisely how Rails 2.2 handles internationalization! The above form is written as:


<%= I18n.t :login %>
<%= I18n.t :password %>

Why? Because I18n.t takes a string key, and returns the text, like so:


I18n.t("login") => "Login: "
I18n.t("password") => "Password: "

Where are the actual keys and strings stored? They’re inside config/locales/LANGCODE.yml. For example, English keys (since English is the default language) are stored in en.yml.

When you invoke the rails command to build a new app, by default, en.yml will have these contents:


# Sample localization file for English. Add more files in this directory for other locales.
# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.

en:
hello: "Hello world"

You can easy add new strings; for our input form, we’d use something like:


login: "Login: "
password: "Password: "
# ...

And so on. Also, note that in your environment.rb file, there’s a new (commented-out) line, like so:

# config.i18n.default_locale = :de

You can uncomment this to set the default locality to German. Or French. Or Japanese. Or Arabic. Or whatever you want!

Also, what about templated strings–like “Hello, <your name>?” The solution is something well-used in different programming languages–simply use a token in your string, and spcify the value on-the-fly, like so:


# in en.yml
greeting: Hello, {first_name}!

# in the code
<%= I18n.t :greeting, :first_name => "Muhammad" # => Hello, Muhammad!

Finally, how do you change the locale? By specifying I18n.locale, like so:

I18n.locale = "de-DE" # German

There’s more to it than this, but we’ll leave it at this for now. So enjoy!

And don’t forget the key lesson of this whole shpiel–internationalize your application! Gone are the days of relying on just one language! The web is too big! (And your users will love you for it!)

About Ashiq Alibhai

Ashiq Alibhai, PMP, has been a Rails aficionado since 2007, and developed web applications since early 2003, where he learned PHP in one summer. As the driving-force behind RailsRocket and the Launchpad project, he seeks to share the ease of development with Rails far and wide.
This entry was posted in Development and tagged , , . Bookmark the permalink.

5 Responses to Internationalization (I18n) in Rails 2.2

  1. Swami Atma says:

    Nice post. There a couple small mistakes though:

    - Internationalization has 20 letters: i + 18-letters + n

    - I18n.locale = “de-DE” # Dutch should say: I18n.locale = “de-DE” # German or Deutsch in native

    Dutch is the languages spoken in the Netherlands and Deutsch is how you say German in German.

  2. ashes999 says:

    Oops! Good catch, thanks. I was always confused about Dutch vs. Deutsch.

  3. rajib says:

    thanks
    your article is helpful…
    can u make this article more like a tutorial…
    That would be really helpful for people like me
    :)

  4. ashes999 says:

    Not sure how to make it more tutorial-like….

    1) Just substitute strings for I18n.t :key
    2) And key: value pairs into en.yaml

    That’s it!

  5. K. Meier says:

    A nice idea to first show a simple self-made solution and then compare it to the official framework.
    I have also written an overview about the rails internationalisation, with some details about validation messages. See link above.