#138
Dec 01, 2008

I18n

Internationalization is one of the biggest additions in Rails 2.2. See how the basics work in this episode.
Download (21.2 MB, 7:36)
alternative download for iPod & Apple TV (12.5 MB, 7:36)

Resources

<!-- users/new.html.erb -->
<p>
  <%= f.label :language, "Language" %><br />
  <%= f.select :language, [['English', 'en'], ['Wookieespeak', 'wk']] %>
</p>

<!-- products/index.html.erb -->
<% title t('welcome.title') %>
<p><%= t 'welcome.paragraph' %></p>
<h2><%= t 'products.title' %></h2>
<% for product in @products %>
  <h3>
    <%= link_to h(product.name), product %>
    <%= number_to_currency(product.price) %>
  </h3>
  <div class="date_released">
    <em><%= t 'products.released' %>: <%= product.created_at.strftime("%m/%d/%Y") %></em>
  </div>
<% end %>
# sessions_controller.rb
flash[:notice] = t('flash.login')

# controllers/application.rb
before_filter :set_user_language
def set_user_language
  I18n.locale = current_user.language if logged_in?
end
# config/locales/en.yml
en:
  welcome:
    title: "Welcome"
    paragraph: "Thank you for visiting our store. Please browse through the products below and buy some stuff. You'll love the unique quality and workmanship put into these items."
  products:
    title: "Products"
    released: "Released"
  flash:
    login: "Logged in successfully."

# config/locales/wk.yml
wk:
  welcome:
    title: "Wyah"
    paragraph: "Wyaaaaaa. Ruh ruh. Huwaa muaa mumwa. Wyogg, ur oh. Wua ga ma uma ahuma ooma. Ruh gwyaaaag. Youw."
  products:
    title: "Mauhwaa"
    released: "Ruhhha"
  flash:
    login: "Wohooohaaa"
  number:
    format:
      precision: 3
      separator: '|'
      delimiter: '-'
    currency:
      format:
        unit: '$'
        precision: 2
        format: '%u%n'

RSS Feed for Episode Comments 58 comments

1. MTH Dec 01, 2008 at 00:44

Yeah, that's what I need!

And now I can remove Globalite for sure 8-)

Thanks, Ryan!


2. Ben Dec 01, 2008 at 00:46

Nice Screencast!
All we need now is a good way to do model translation... :)


3. Andreas Dec 01, 2008 at 01:13

Great Screencast, thanks Ryan.
I've been doing apps in multiple languages for quite some time now. I started with ruby-gettext about 2 years ago and just switched to Rails i18n in a recent app. It's really great to have an API for i18n included in Rails.

For those who are interested in i18n - I'm posting thoughts, ideas and experiences with Rails i18n to my blog from time to time.


4. QuBiT Dec 01, 2008 at 01:23

Wookie wookie ^^ ...
or in other words ^^ ... just great.


5. Andreas Dec 01, 2008 at 01:25

Btw, I modified the rails-i18n repository with many core translations you mentioned and made it a plugin. I found it a bit easier and more maintanable to simply update a plugin instead of copy&pasting the core translations into my own .yml files every time.

The plugin can be found at http://github.com/zargony/rails-i18n


6. Andrew Dec 01, 2008 at 01:52

Another great Railscast! Sorry that this is off topic, but I've been using the instance variable @current_user in my Rails app. Would switching to the local variable reap any benefits (like speed improvements?) Thanks!


7. aurels Dec 01, 2008 at 02:40

Awsome!

Does anyone know if it will be possible to have some specific locale strings into engines?


8. Dejan Dimic Dec 01, 2008 at 02:42

Any decent web application need to have localisation sooner or latter. Now this task is much easer and this screen cast is great first step in localisation process.


9. Nils R Dec 01, 2008 at 03:51

Woohoo!

Have been waiting for this screencast. Will have to watch it when i'm back at home...


10. grigio Dec 01, 2008 at 06:18

Thanks for this screencast!!

@Ben:
For the model translation there is Globalize2 http://github.com/joshmh/globalize2/tree/master


11. Ryan Bates Dec 01, 2008 at 07:47

@Ben, I may cover model translation after this series on Rails 2.2 is done, thanks for the suggestion.

@Andrew, the "current_user" in my case is actually a method call. I prefer this over a before_filter which sets a @current_user because it will only load the current user if it needs access to it, not on every page all the time.

@David, thanks, marked.


12. Jean-Marc Dec 01, 2008 at 07:52

Translating the text and formats has always been important but it's half the battle when it comes to internationalization.

The other half is letting the user choose the language and having those pages being indexed in their specific languages.

I personally like to have the language as part of the URL because it makes for a very simple selection mechanism (and it makes every entities distinct one even for the search engines).

You have any thoughts on that level??


13. Ryan Bates Dec 01, 2008 at 07:58

@Jean, you could do this fairly easily with subdomains. Since the language is set in a before filter you could combine this episode with #123 on subdomains.
http://railscasts.com/episodes/123-subdomains


14. chovy Dec 01, 2008 at 09:44

Great screencast...the only thing missing is database translations.

Also, once you start translating the units of currency, you'll have to start converting prices from say "dollars to euros". Either dynamically based on the current exchange rate, or hard coded somewhere.


15. RailsCasts Fan Dec 01, 2008 at 11:35

Good work Ryan, like always. ;-)

i18n is very important and this screencast is a good start to start with internationalization.


16. Mark Wilden Dec 01, 2008 at 11:39

Locale is pronounced "loh-CAL".


17. Andreas Dec 01, 2008 at 11:58

@Jean-Marc: that should be easy. You could e.g. use a (configurable) constant hash as a tld=>locale lookup, e.g.

TLD_LANGS = { 'com' => 'en', 'de' => 'de' }

and use a before_filter in ApplicationController to set the locale based on the current request host like

I18n.locale = TLD_LANGS[request.host.split('.').last] || 'en'


18. Steve Dec 01, 2008 at 13:16

Is there any reason an application shouldn't display the preferred locale set in the browser? Is there an easy way to access this locale?


19. Michael Dec 01, 2008 at 15:47

Nice Screencast!

Maybe it is nice to add something like routes translations? Is that even possible?


20. Pawel Dec 02, 2008 at 01:33

Nice screencast, as always, thanks!

What if Wookie would like to enter some number in the form? The application needs to convert this number and probably save it to db. What are best practices to achive that?


21. Jean-Marc Dec 02, 2008 at 10:32

@Steve,

using the browser settings is one of the step toward presenting the correct language... at the same time limiting yourself to the preferred language of the browser would detract some of your users (for example, my browser here has a french default but I still prefer to view some sites in english, even when french is offered).

At the same time, you have to take in account that browsers are not the only client your website will have (I can still recall one website I was asked to look into, they were indexed in one of the three languages the site was available into... the reasons... language selection was done through cookies and search engines don't understand cookies).

The language selection process is important. I usually take an approach similar to the ibm.com website (having the locale being part of the url)... as Ryan suggests, sub-domains can achieve the same trick.

Jean-Marc


22. Quotes Dec 02, 2008 at 14:20

It is really great to be able to internationalize your application. We needed I18N for long time.

Thanks


23. Marc-Antoine Dec 03, 2008 at 13:32

Thanks again Ryan for this great tutorial. In the past, I have used Globalize to translate UI content. Sometimes when the layout was a little bit different from english to french, it was more easy just to create an other view to handle the job. Something like index.fr.html.erb. Can we do so in 2.2?

Thanks

Marc


24. pulkit Dec 03, 2008 at 21:43

Power Pack Performance of rails 2.2 !!!!


25. Andrea Dec 04, 2008 at 01:25

Thanks! Great episode! But what about models and validation translation? Is possibile with I18n? If so maybe you could show us how to with an advanced episode xD


26. Andreas Dec 04, 2008 at 03:15

@Andrea: Yes, models, attributes and validation messages can be translated as well as time/date formats or e.g. output of distance_of_time_in_words. You might want to have a look at the various "localized_dates" and "rails-i18n" repositories on github.


27. phaenotyp Dec 06, 2008 at 05:42

Woohoo!

Thank you, thank you, thank you!

Great screencast and exactly what I needed.


28. Josh Dec 07, 2008 at 15:19

Awesome screencasts... I've been a long-time fan.

Can you maybe give me a tip on what software you use to create these screencasts?

I'd like to produce some of my own, and yours are always very high quality. Any hints you can offer would be great!


29. Nando Vieira Dec 07, 2008 at 16:29

Make sure you check the plugin Localized Templates... translating long texts can be hard, so I prefer to have templates fully translated.

http://github.com/josevalim/localized_templates/


30. Gavin Laking Dec 08, 2008 at 05:04

Thanks again Ryan- great cast.

Josh: I think Ryan uses iShowU for his screencasts, but I expect he has a decent-ish microphone and setup because it sounds very clear and is well edited.

Gav


31. Josh Dec 08, 2008 at 13:54

@Gavin: Thanks for the tip!
I'll check out iShowU...


32. Qup Dec 09, 2008 at 07:37

@Mark Wilden

'Locale is pronounced "loh-CAL".'

It's not in my "loh-cAIL". ;-)


33. Jakob Skov-Pedersen Dec 11, 2008 at 07:24

This is cool I even created a Textmate command to help when localizing an existing app. Just select some text, and run it, it will ask for a desired translation name, and insert the appropriate <%=t 'name' %> for you. The translation line that you can insert into a yaml file is copied to the clipboard, ready for pasting ;) That makes it so much faster.

You can find it here if you're interested:
http://gist.github.com/31133


34. Slangasaurus Dec 11, 2008 at 09:48

My site is very language centric, and recently i used some fragment caching to speed up page loads. Has anyone tried I18n with fragment caching?


35. ohaleck Dec 12, 2008 at 03:15

Hurray! My voice has been heard!
Thank you so much Ryan for this screencast!!


36. Martin Dec 19, 2008 at 12:08

Why do I get ActionView::TemplateError (undefined method `each' for false:FalseClass) when I use <%= t 'hello' %> in a view??


37. IV Dec 25, 2008 at 01:46

Great RailsCast, thanks!
[pt] Grande Railscast, obrigado!


38. Niklas K. Feb 01, 2009 at 09:26

Hello,
nice screencast.
As I require full customization functions via the admin webinterface of my Rails app, I cannot afford restarting the server everytime a locale is changed/added. Do you know of a way to disable that or flush the cache at runtime?


39. Niklas K. Feb 01, 2009 at 09:53

Found it:
I18n.reload!


40. Dave Feb 06, 2009 at 08:41

<% title t('welcome.title') %>

does this mean we can no longer do:

<%= title t('welcome.title') %>

I have tried it and it displays the entire :title in the browser.


41. Helmut Feb 18, 2009 at 06:39

Hey i would like to know if someone has approach I18n for the active merchant plugin
because i'm trying to do it but i can't make it work properly. I
receive the errors messages only in english, i can't get'em translated.
Thanks in advance!


42. Dave N. Feb 24, 2009 at 15:10

Anyone have any suggestions for key names and organization of translation files?


43. Odaki Mar 02, 2009 at 15:42

Why the locale files are not included within rails ? It's would be easier to update. And every rails version will have the same locales files.


44. Petko Apr 11, 2009 at 12:38

Excellent railcast, Ryan! Thank you very much. It answered all questions that I had about Rails 2.3 I18n features :)


45. Gavin May 27, 2009 at 13:50

Is there a preferred method for translations of large amounts of copy? For example, if there is a "terms of service" or "privacy policy" page, what is the best way to handle the large amount of copy in multiple languages? Thanks so much for your help.


46. Amy Aug 15, 2009 at 21:42

Wookie! ha!

This was just the Railscast that I needed---I was going to implement I18N in a different way. Short and right to the point. Thanks, Ryan!


47. Darren Oct 02, 2009 at 10:39

I noticed you used a 'ss' shortcut/alias to start your server. How might you do that Ryan?


48. mario oyunları May 05, 2010 at 11:55

good article and thanks admin.


49. Ai Jun 04, 2010 at 14:25

Great episode! Arigato Ryan :)


50. sesli chat Jun 10, 2010 at 04:23

thank you very much for sharing


51. sesli chat Jun 10, 2010 at 04:24

thanks


52. seslimazi Jun 10, 2010 at 04:24

thank you so much


53. seslimazi Jun 10, 2010 at 04:24

thank you so much


54. sesliyes Jun 10, 2010 at 04:25

thank you


55. hotels Jun 27, 2010 at 06:28

Thanks.It's very nice post
thanks for this useful post
i really like it
David Heinemeier Hansson


56. metin2 pvp serverlar Jun 29, 2010 at 05:00

nice post thanks all..


57. sesli chat Jul 20, 2010 at 02:01

Thanks admin


58. sesli chat Jul 21, 2010 at 11:12

thanks for sharing


59. sesli chat Jul 21, 2010 at 11:12

thank you very much


60. sesli chat Jul 21, 2010 at 23:18

Thanks admin Have been waiting for this screencast. Will have to watch it when i'm back at home


61. ankara oto kiralama Jul 22, 2010 at 07:28

Thanks. the thing i love about open boards that allow anyone to post is that it gives an opportunity for the select few “special” to show us just how much they fail at life. if you don’t have anything positive to say simply don’t post. this was not intended to be a timeline for Apple’s accomplishments. it was a joke. most got it. some didn’t. but why the disrespectful comments and attitude? i think it is quite humorous how for some this is their only opportunity to make a difference through their self-proclaimed obnoxious and “witty” posts where they try to slam others. here is a new invention for you select few… iFail. yes, you fail. get a life and swing your e-peen somewhere else.


62. superonlinesesli Aug 03, 2010 at 10:58

very nice site Thank you


63. seslialmanya Aug 04, 2010 at 23:33

tHANKS thank you admin


64. seslialmanya Aug 04, 2010 at 23:34

seslialmanya thank you name my seslialmanya


65. Diamond Tools Aug 05, 2010 at 06:21

Great post, do you mind if I can reference back to it? I've been blogging about this and trying to find out a little more info on this, thanks for sharing it.


66. free directory list Aug 11, 2010 at 22:31

Ryan, could you show the view that is calling this template?


67. Wholesale hats Aug 20, 2010 at 20:52

I recently came across your blog and have been reading along.
I thought I would leave my first comment. I don’t know what to say except that I have enjoyed reading.Nice blog,I will keep visiting this blog very often.


68. mcqueen shoes Aug 21, 2010 at 01:05

This is truly fantastic stuff - thank you too your knowledge


69. Sesli panel Aug 21, 2010 at 07:05

tenku tescilpanel


70. air jordan retro 13 for sale Aug 22, 2010 at 23:12

thanks for the great screencast. I have become a huge fan of this website and I really cant wait to read you next posts! Thanks for your work and sharing your information. I going to download it


71. video games Aug 23, 2010 at 17:34

Excellent railcast, Ryan!


72. louis vuitton shoes Aug 26, 2010 at 21:10

Thanks for sharing your article. I really enjoyed it. I put a link to my site to here so other people can read it. My readers have about the same interets


73. Wholesale Electronics Aug 27, 2010 at 00:24

Discount Wholesale Electronics, Wholesale Cell Phones, Electronic Gadgets and More from the Best Dropship Wholesaler


74. louis vuitton neverfull Aug 29, 2010 at 23:07

I recently came across your blog and have been reading along.
I thought I would leave my first comment. I don’t know what to say except that I have enjoyed reading.Nice blog,I will keep visiting this blog very often.


75. snow boots Aug 30, 2010 at 21:18

I modified the rails-i18n repository with many core translations you mentioned and made it a plugin. I found it a bit easier and more maintanable to simply update a plugin instead of copy&pasting the core translations into my own .yml files every time.


76. snow boots Aug 30, 2010 at 21:19

Great episode! But what about models and validation translation? Is possibile with I18n? If so maybe you could show us how to with an advanced episode xD


77. levis belts Sep 01, 2010 at 20:45

Came across your blog when I was searching bing I have found the bit of info that
I found to be quite useful.

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player
Give Back to Open Source