#256 I18n Backends
Mar 07, 2011 | 11 minutes |
Views
Internationalization is easy to add in Rails, but the YAML files can be difficult to manage. In this episode I show how to use Redis for managing the translations through a web interface.
- Download:
- source codeProject Files in Zip (99.2 KB)
- mp4Full Size H.264 Video (19.2 MB)
- m4vSmaller H.264 Video (12.4 MB)
- webmFull Size VP8 Video (28.2 MB)
- ogvFull Size Theora Video (26.1 MB)
Thanks Ryan, excellent screencast!
Was just looking at something like that! Thanks for yet another great railscast.
After translating a simple rails app (starting with nifty-generators) I'm very happy to understand translation backends.
I very much like the Idea of a translation web-interface, but I'm not yet sure about redis. Maybe it makes sense in a large environment, but for my little personal use it's too much effort to run another server. Additionally I like the idea of having a file unter version control.
However it would be great to use a web-interface that is capable to trace all the "missing translation" entries when I run my app in development mode and to then display them in a matrix (item by supported language) to get an overview in what's missing.
Is there a gem like this out there?
Excellent!
Congratulations on episode 2**8 = 256
Nice solution! You can also make a webinterface to modify the yaml files with the translations. That way you don't need to switch to another backend.
This could be really great when using it with Tolk (https://github.com/dhh/tolk).
Thanks a lot!
How about tolk https://github.com/dhh/tolk?
Nice 1<<8 episod :)
Thanks again for this great post.
I'm living in Quebec (Canada). Every projects I'm working on must accomodate French an English users. The approch presented in this screencast is very simplice and neary unusable inside medium and large projects.
For us, translation is part of our workflow.
Generally, before beginning a project, we decide the language used by default (language inside the code). English is often appropriate. Then, during the modeling stage, we select names to be used for models and attributes in both french and english. (I'm working on a generator that will create the yml files under config/locales/models/... and the appropriate keys).
Combined with a generic series of translations, this is sufficient for 99% of administrative views. It is very easy to combine with meta_search, simple_form and other gems.
For the translation of database content, views and static views, we use several techniques. It depends on the client context.
Some content must exist simultaneously in both languages. Others do not have this restriction. Some pages are so different from one language to another... So we produce them separately. (about.en.html.erb, about.fr.html.erb...) we also add by composition some methods to the models.
If one day you have any interest, I would be happy to share my screen with Skype and walk you through one of my projects... In English of course!
Hi, do you use something like globalize3 for content translation?
I curious about your approach to this problem (e.g. do you build something from scratch or use something almost-ready? How do make the translators work? etc...)
I like Translate (https://github.com/newsdesk/translate) which lets you edit the yml files from a web interface with some smart search options.
Funny how you'd do a Railscast on i18n just a couple of days after I took a lab day to explore webtools for handling the translation process.
We have about 3000 strings translated into five languages. Editing yaml-files in this situation will cause brain damage.
For now, we've settled on http://webtranslateit.com, but there are others like http://99translations.com. They provide a really nice translation GUI. Importing our locale files took a while, but the export was quick and gave me the opportunity to do a massive cleanup of our translation keys.
I feel that when an internationalized project grows big, there is a large payoff in using a professional translation tool. Spend your time on your app, instead of maintaining a custom tool for translations. If your translation files are big, you'll make the money you spend on the translation tool back in very little time.
Oh, and congratulations on your 2**8th episode!
Great screencast Ryan! Would be awesome to have one focusing solely on Redis and caching one day.
Thanks a lot for update about tolk from dhh! Will try soon, but doc is already very promising...
Thank you for another great screencast!
Speaking of internationalization, I'd really enjoy a Railscast on the woes of document and string encodings with Ruby 1.9.2 and Rails (the good ole' multibyte US-ASCII error). It's a real headache for many Rails developers. But I do realize that it's not really a Rails issue.
Ryan, have you thought about processing video in rails. I think it would be a great screencast.
For those who are interested: there is a Redis backed i18n solution in my redis-store gem (beta4 version): https://github.com/jodosha/redis-store/blob/master/lib/i18n/backend/redis.rb
Cannot wait to try this with a key-value store. Ruby wasn't happy when I put unicode string (??? - peace) in yaml file. Ended up using ActiveRecord with DB round trip overhead.
Wow, that's cool. I did something very similar a few months ago for a client and made it open source. It's using Mongodb backend instead, and there is only one big form where user can enter details. Check it out here: https://github.com/hubertlepicki/GoTranslateYourself
I found it useful to provide default dummy fallback locale -- in dev.yml file -- so that even English-speaking clients can make ammendments to wording on the site such way.
Actually I changed my mind after watching this episode again, and made imporovements to the backend. Supports Redis and MongoDB, nicer UI. Thanks for showing me chainable backend in this episode.
As always, you're right on time -- I had to improve this engine for another client, and this episode helped a lot!
New project is here:
https://github.com/amberbit/translator
Thanks for yet another great episode! The :escape options is not taken into account when using the i18n::Backend::Chain though, so '.' are always escaped.
It seems that's there's a pull request fixing it waiting:
https://github.com/svenfuchs/i18n/pull/85
Hi, I have followed the railscast to implement the solution using Redis as suggested as I thought it was brilliant :)
I am using redistogo.com as my redis server. But something I don't get is that the performance are DISASTROUS, I am talking minutes to load every single page. I thought you said that using redis would load the I18n store in memory ? Am I mistaken ? Because I think everytime transalt accesses the store it goes to redis... and obviously it takes times a bit of time for the connection, etc, but since I use it massively it simply kills the the performance of the site. I tried using the simple hash and this works just fine...
Alex
Great screencast Ryan, thank you! For mongodb store check here:
http://stackoverflow.com/questions/5315470/rails-i18n-backend-with-mongodb-mongoid/5591463#5591463
I don't know how, Ryan, but it looks like you are reading my mind. I just need this for my current project!
-----
www.congrats-from.me
I do not fully understand how Redis has better performance than active record? Are they both not essentially accessing data that is in RAM, just in two separate ways? Are there more layers to go through when accessing data via ActiveRecord?
I'm trying to store my I18n using redis for example :
but my key change to introlabeltitle even my controller log like :
Parameters: {"commit"=>"Submit", "authenticity_token"=>"ZYoK5MMixIz9hiN8keOd9OTkKo6dBYluATYoyQDbmrY=", "utf8"=>"?", "value"=>"Hello World", "locale"=>"en", "key"=>"intro.label.title"}
and inside the redis-cli my key change to "en.intro\x01label\x01title"
here is my initializer :
and my controller
Thank you and sorry for my bad english
Bastien was already pointed at this issue, you need to apply patch from there
Just what I needed today - thanks Ryan!
We think that the very basic i18n approach of rails needs some improvement.
That is why we built a product to handle translations much more easily: phrase
If you have a rails/ruby project that uses the i18n gem, this could be the right thing for you to use.
Hi, it seems interesting, I'm curious about the price for the "Beginner" plan once the beta stage will end.
It would be really useful an interface for the globalize3 gem, have you planned it?
Hi Aldo,
sorry for the late reply, just found out about your posting.
We haven't planned support for globalize3 yet, but it definitely seems interesting.
We will have a look at it soon. Have you already had a chance to try phrase?
No I've not yet tried phrase, what about the price?
No I've not yet tried phrase, what about the price?
Thanks for the great article! I'm using redis and translations view for my russian ("ru") translations. The problem is, in the translations#index view my translation values look like escaped unicode entities:
ru.foo: [\u041d\u0430]
while when I use t('foo') in my views the value is output properly. With English translation everything is fine of course. Does anyone know what could cause that "broken" output in translations#index view?
I have done exactly as in this episode. When I fetch translations from redis they are printed on translations page like this:
ru.items.title: ["\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435"]
I get the same if I print it to the log file. In the view with ru locale when using t('items.title') it's translated to "Название".
OK, I ended up translating this manually using gsub() as described here:
http://stackoverflow.com/questions/7015778/is-this-the-best-way-to-unescape-unicode-escape-sequences-in-ruby
Ugly solution, but it works.
This is a great episode! 2 years later and still very relevant.
However, I found that using Redis as my I18n score has a noticeable performance cost - even when running on the same server as my Rails app. I wrote a very simple key-value cache gem that memoizes the translations. In my case it greatly improved my site's performance.
CachedKeyValueStore
Why not use the database store in development. Add all translations you want, then export from DB to yaml file which is used in production?