Rails: Интернационализация строк Javascript?
Итак, у нас есть существующее приложение Rails 2.3.5, которое вообще не поддерживает интернационализацию. Теперь я хорошо знаком с Rails I18n, но у нас есть много выходных строк внутри /javascripts/
. Я не большой поклонник такого подхода, но, к сожалению, уже слишком поздно исправлять его.
Как мы можем интернационализировать строки, хранящиеся в JS файлах в приложении Rails? Rails даже не обслуживает файлы JS...
Я думаю, что всегда мог бы использовать приложение Rails для JS файлов, но это выглядит довольно грубо. Есть ли плагины для этого?
Ответы
Ответ 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;
Ответ 2
Балибу заброшен. Используйте i18n-js: https://github.com/fnando/i18n-js
Ответ 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/