Rails: Internationalizing Javascript Strings?

So, we have an existing Rails 2.3.5 application that does not support internationalization at all. Now I am familiar with Rails I18n, but we have many output lines inside /javascripts/ . I am not a big fan of this approach, but, unfortunately, it is too late to correct it.

How can we internationalize strings stored in JS files in a Rails application? Rails doesn't even serve JS files ...

I think I could always use a Rails application for JS files, but that looks pretty rude. Are there any plugins for this?

+52
javascript ruby-on-rails internationalization
Apr 23 '10 at 20:20
source share
10 answers

Why not just like that:

 <script type="text/javascript"> window.I18n = <%= I18n.backend.send(:translations).to_json.html_safe %> </script> 

Then in JS you can do things like:

 I18n["en-US"]["alpha"]["bravo"]; 

I wrapped mine in the application helper.

 def current_translations @translations ||= I18n.backend.send(:translations) @translations[I18n.locale].with_indifferent_access end 

Then my call in my application application.html.erb looks like this:

 <script type="text/javascript"> window.I18n = <%= current_translations.to_json.html_safe %> </script> 

This avoids the need to know the current locale in JavaScript.

 I18n["alpha"]["bravo"]; 

or

 I18n.alpha.bravo; 
+87
May 15 '12 at 11:48 p.m.
source share

Balibu is abandoned. Use i18n-js: https://github.com/fnando/i18n-js

+18
Feb 16 2018-12-12T00:
source share

Ryan's solution above is excellent, except that the backend must be initialized if it has not already been.

 I18n.backend.send(:init_translations) unless I18n.backend.initialized? # now you can safely dump the translations to json 
+7
Sep 18 '13 at 2:03
source share

For rails 3 applications you can do this:

Create the i18n.js.erb file and add it to your application.js. And add this piece of code to the file.

 <% @translator = I18n.backend @translator.load_translations @translations ||= @translator.send(:translations)[I18n.locale][:javascript] %> window.I18n = <%= @translations.to_json.html_safe %> 

I also use my translations to not have a huge javascript file. My scope: javascript.

Hope this helps someone!

+5
Oct. 19 '13 at 15:29
source share

Why not just this in your Javascript file:

 var a_message = "<%= I18n.t 'my_key' %>" 

For this to work, you must add .erb to your Javascript extension.

You may also need to add the following line at the top of your Javascript file if you are not using ruby> = 2.0.

 <%# encoding: utf-8 %> 

See the last comment of the accepted answer in this thread for more information: Encoding problems in javascript files using rails resource pipeline

+4
Jun 25 '13 at 19:57
source share

Babilu is a Rails plugin that does this for you.

+2
Apr 23 '10 at 20:22
source share

Another option that may be useful:

Suppose you have a Language (slug) model that contains all available languages. It handles cases where there is no translation (it is replaced by the standard version of the locale)

assets / javascript / i 18n.js.erb

 <% @translator = I18n.backend @translator.load_translations translations = {} Language.all.each do |l| translations[l.slug] = @translator.send(:translations)[l.slug.to_sym] end @translations = translations %> window.I18n = <%= @translations.to_json.html_safe %> window.I18n.t = function(key){ if(window.I18n[current_locale]){ el = eval("I18n['"+current_locale+"']." + key); } if(window.I18n[default_locale] && typeof(el) == 'undefined'){ el = eval("I18n['"+default_locale+"']." + key); } if(typeof(el) == 'undefined'){ el = key; } return el; }; 

view / layout / application.html.erb

 ... <%= javascript_tag "var current_locale = '#{I18n.locale.to_s}';" %> <%= javascript_tag "var default_locale = '#{I18n.default_locale}';" %> ... 

In your javascript code, you can translate like this:

 // current_locale:fr , default_locale:en // existing translation (in french) I18n.t('message.hello_world'); // => Bonjour le monde // non-existing translation (in french) but existing in english I18n.t('message.hello_this_world'); // => Hello this world // non-existing translation (french & english) I18n.t('message.hello_this_new_world'); // => message.hello_this_new_world 

Hope this helps!

+2
May 24 '14 at
source share

Ryan solution is brilliant. But in order not to include the entire file, you should use: @translations[I18n.locale].with_indifferent_access["alpha"] instead of I18n.backend.send(:translations)["alpha"]

+1
Jun 05 '13 at 11:31
source share

I18n-js works great for me, and I would recommend it. If you use it to rewrite the branch , the plugin will include the file /assets/i18n/filtered.js , which displays exactly what @ ryan-montgomery answered without having to do anything manually.

This way you can use the same backend translations with the Rails t(:key) I18n.t('key') and using I18n.t('key') in Javascript on the interface.

0
Oct 13 '13 at
source share

For applications like the one you described, β€œwhich doesn’t support internationalization at all” and β€œfix it too late”, I wrote a very fast approach: jQuery Quick-i18n plugin: https://github.com/katio/Quick- i18n demo (and how to use it): http://johannpaul.net/Quick-i18n/

0
Oct. 14 '13 at 0:14
source share



All Articles