Rails: интернационализация строк JavaScript? - PullRequest
54 голосов
/ 24 апреля 2010

Итак, у нас есть приложение Rails 2.3.5, которое вообще не поддерживает интернационализацию. Теперь я хорошо знаком с вещами Rails I18n, но у нас есть много выходных строк внутри /javascripts/. Я не большой поклонник этого подхода, но, к сожалению, уже слишком поздно, чтобы исправить это.

Как мы можем интернационализировать строки, хранящиеся в файлах JS, в приложении Rails? Rails даже не обслуживает файлы JS ...

Я думаю, я всегда мог бы заставить приложение Rails обслуживать JS-файлы, но это кажется довольно грубым. Есть ли плагины для этого?

Ответы [ 10 ]

94 голосов
/ 16 мая 2012

Почему бы не что-то простое, например:

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

Тогда в JS вы можете делать такие вещи, как:

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

Я завернул свой помощник в приложении.

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

Тогда мой вызов в моем application.html.erb выглядит так:

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

Это позволяет избежать необходимости знать текущую локаль в JavaScript.

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

Или

I18n.alpha.bravo;
18 голосов
/ 16 февраля 2012

Балибу заброшен. Используйте i18n-js: https://github.com/fnando/i18n-js

9 голосов
/ 18 сентября 2013

Решение Райана, описанное выше, является идеальным, за исключением того, что серверная часть должна быть инициализирована, если это еще не было.

I18n.backend.send(:init_translations) unless I18n.backend.initialized?
# now you can safely dump the translations to json
6 голосов
/ 19 октября 2013

Для приложений rails 3 вы можете сделать следующее:

Создать файл i18n.js.erb и добавить его в ваш application.js.И добавьте этот кусок кода в файл.

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

window.I18n = <%= @translations.to_json.html_safe %>

Я также ограничил свои переводы, чтобы у меня не было огромного файла JavaScript.Моя сфера деятельности: javascript.

Надеюсь, это кому-нибудь поможет!

5 голосов
/ 25 июня 2013

Почему бы просто не указать это в своем файле Javascript:

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

Чтобы это работало, вы должны добавить .erb к расширению вашего файла Javascript.

Вам также может понадобиться добавить следующую строку вверху вашего файла Javascript, если вы не используете ruby> = 2.0.

<%# encoding: utf-8 %>

См. Последний комментарий о принятом ответе в этой теме для получения дополнительной информации: Проблемы с кодировкой в ​​файлах JavaScript с использованием конвейера ресурсов rails

2 голосов
/ 24 мая 2014

Еще один вариант, который может быть полезен:

Предположим, что у вас есть модель Language (slug), которая содержит все ваши доступные языки. Он обрабатывает случаи, когда есть отсутствующий перевод (он заменяется версией локали по умолчанию)

активы / JavaScript / i18n.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;
};

вид / макет / application.html.erb

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

В вашем коде javascript вы можете перевести так:

// 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

Надеюсь, что это поможет!

2 голосов
/ 24 апреля 2010

Babilu - это плагин Rails, который делает это за вас.

1 голос
/ 05 июня 2013

Райан раствор блестящий.Но чтобы не включать весь файл, вы должны использовать: @translations[I18n.locale].with_indifferent_access["alpha"] вместо I18n.backend.send(:translations)["alpha"]

0 голосов
/ 14 октября 2013

Для приложений, подобных описанному вами, «которые вообще не поддерживают интернационализацию» и «уже слишком поздно, чтобы это исправить», я написал очень быстрый подход: плагин jQuery Quick-i18n: https://github.com/katio/Quick-i18n демо (и как его использовать): http://johannpaul.net/Quick-i18n/

0 голосов
/ 14 октября 2013

I18n-js отлично работает для меня, и я бы порекомендовал его. Если вы используете ветвь перезаписи , то плагин будет включать файл /assets/i18n/filtered.js, который выводит именно то, что ответил @ ryan-montgomery, без необходимости что-либо делать вручную.

Таким образом, вы можете использовать те же переводы на сервере с помощниками Rails t(:key) и использованием I18n.t('key') в Javascript на внешнем интерфейсе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...