wake-up-neo.com

Rails: Internationalisierung von Javascript-Strings?

Wir haben also eine bestehende Rails 2.3.5-App, die die Internationalisierung überhaupt nicht unterstützt. Nun, ich bin mit dem Zeug von Rails I18n bestens vertraut, aber wir haben eine Menge Ausgangsstrings in /javascripts/. Ich bin kein großer Fan dieses Ansatzes, aber leider ist es zu spät, um ihn zu beheben.

Wie können Strings, die in JS-Dateien in einer Rails-App gespeichert sind, internationalisiert werden? Rails bietet nicht einmal die JS-Dateien an ...

Ich denke, ich könnte die Rails-App immer für die JS-Dateien bereitstellen, aber das scheint ziemlich ekelhaft zu sein. Gibt es Plugins, um dies zu tun?

53
Matt Rogish

Warum nicht etwas einfaches wie:

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

Dann können Sie in JS Folgendes tun:

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

Ich habe meinen in einen Anwendungshelfer eingepackt.

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

Dann sieht mein Aufruf in meiner application.html.erb so aus:

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

Auf diese Weise können Sie vermeiden, das aktuelle Gebietsschema in JavaScript kennen zu müssen.

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

Oder

I18n.alpha.bravo;
93
Ryan Montgomery

Balibu wird aufgegeben. Verwenden Sie i18n-js: https://github.com/fnando/i18n-js

18

Ryans Lösung ist perfekt, es sei denn, das Backend muss initialisiert werden, falls es noch nicht geschehen ist.

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

Für Rails 3-Anwendungen können Sie Folgendes tun:

Erstellen Sie eine i18n.js.erb-Datei und fügen Sie sie Ihrer application.js hinzu. Und fügen Sie diesen Code In die Datei ein. 

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

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

Ich übersetze auch meine Übersetzungen, um keine riesige Javascript-Datei zu haben. Mein Anwendungsbereich ist: Javascript.

Hoffe es hilft jemandem!

6
Vince V.

Warum nicht einfach das in Ihrer Javascript-Datei:

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

Damit dies funktioniert, müssen Sie der Dateierweiterung der Javascript-Datei .erb hinzufügen.

Sie müssen möglicherweise auch die folgende Zeile oben in Ihrer Javascript-Datei einfügen, wenn Sie nicht Ruby> = 2.0 verwenden.

<%# encoding: utf-8 %>

Weitere Informationen finden Sie im letzten Kommentar der akzeptierten Antwort in diesem Thread: Probleme bei der Codierung von JavaScript-Dateien mit der Rails-Asset-Pipeline

5
Dany Marcoux

Eine weitere Option, die hilfreich sein könnte:

Angenommen, Sie verfügen über eine Modellsprache (Slug), die alle verfügbaren Sprachen enthält .. __ behandelt die Fälle, in denen eine fehlende Übersetzung vorliegt (diese wird durch die Standardversion der Ländereinstellung ersetzt)

assets/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;
};

ansichten/layout/application.html.erb

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

In Ihrem Javascript-Code können Sie wie folgt übersetzen:

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

Hoffe, dass es hilft!

2
melalj

Babilu ist ein Rails-Plugin, das dies für Sie erledigt.

2
sblom

Die Lösung von Ryan ist brillant . Um jedoch nicht die gesamte Datei einzuschließen, sollten Sie Folgendes verwenden: @translations[I18n.locale].with_indifferent_access["alpha"] Anstelle von I18n.backend.send(:translations)["alpha"]

1
macler

I18n-js funktioniert super für mich und ich würde es empfehlen. Wenn Sie seinen rewrite-Zweig verwenden, enthält das Plugin eine /assets/i18n/filtered.js-Datei, die genau das ausgibt, was @ ryan-montgomery geantwortet hat, ohne dass Sie etwas manuell tun müssen.

Auf diese Weise können Sie dieselben Übersetzungen im Backend Mit den Rails-Helfern t(:key) und mit I18n.t('key') in Javascript im Frontend verwenden. 

0
robbie613

Für Anwendungen wie die, die Sie beschrieben haben "die keine Internationalisierung unterstützt" und "es ist zu spät, um es jetzt zu beheben", schrieb ich eine sehr schnelle Vorgehensweise: das jQuery-Plugin Quick-i18n: https://github.com/ katio/Quick-i18n demo (und wie man es benutzt): http://johannpaul.net/Quick-i18n/

0