Подтвердить что ты не робот

Rails: Интернационализация строк Javascript?

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

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

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

4b9b3361

Ответ 1

Почему бы не просто так:

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

Ответ 3

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

I18n.backend.send(:init_translations) unless I18n.backend.initialized?
# now you can safely dump the translations to json

Ответ 4

Для рельсов 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

Почему не просто это в вашем файле Javascript:

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

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

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

<%# encoding: utf-8 %>

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

Ответ 6

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

Ответ 7

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

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

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

вид/макет/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

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

Ответ 8

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

Ответ 9

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

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

Ответ 10

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