2010-04-23 16 views
52

Quindi, abbiamo un'applicazione Rails 2.3.5 che non supporta affatto l'internazionalizzazione. Ora, ho familiarità con Rails I18n, ma abbiamo un sacco di stringhe di output all'interno di /javascripts/. Non sono un grande fan di questo approccio, ma sfortunatamente è troppo tardi per sistemarlo ora.Rails: internazionalizzazione delle stringhe Javascript?

In che modo possiamo internazionalizzare le stringhe memorizzate nei file JS in un'app Rails? Rails non serve nemmeno i file JS ...

Sto pensando che potrei sempre avere l'app di Rails che serve i file JS, ma sembra piuttosto schifo. Ci sono plugin per fare questo?

risposta

88

Perché non qualcosa di semplice come:

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

Poi nel JS si possono fare cose come:

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

ho avvolto la mia in un aiutante di applicazione.

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

Poi la mia chiamata nel mio application.html.erb assomiglia a questo:

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

Ciò consente di evitare di dover conoscere il locale corrente in JavaScript.

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

O

I18n.alpha.bravo; 
+7

Funziona perfettamente, grazie. Ho anche implementato questo metodo 't' per renderlo più rave. https://gist.github.com/6a3f1b3a4cf8de889e34 't (" products.price ");' – Oleander

+6

Ho appena trascorso un giorno cercando di far funzionare i18n-js ... la tua soluzione è molto più semplice e ha funzionato immediatamente! – Emmanuel

+0

In effetti funziona perfettamente. Qualche suggerimento su come ottenere solo parte del file in javascript? O separare le traduzioni javascript in un file diverso? Perché ora tutte le traduzioni sono incluse quando ho solo bisogno di 2 frasi. – rept

2

Babilu è un plug-in Rails che fa questo per voi.

1

soluzione Ryan è appartata. Ma di non includere l'intero file è necessario utilizzare: @translations[I18n.locale].with_indifferent_access["alpha"] invece di I18n.backend.send(:translations)["alpha"]

5

Perché non semplicemente questo nel file JavaScript:

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

Per far funzionare tutto questo, è necessario aggiungere al vostro .erb Javascript estensione del file.

Potrebbe inoltre essere necessario aggiungere la seguente riga nella parte superiore del file Javascript se non si utilizza ruby> = 2.0.

<%# encoding: utf-8 %> 

Vedi l'ultimo commento della risposta accettata in questa discussione per ulteriori informazioni: soluzione Encoding issues in javascript files using rails asset pipeline

+4

Una grande ragione per cui questo sarà difficile è la precompilazione delle risorse: quando la risorsa viene precompilata, il javascript verrà inserito nella directory pubblica con il valore predefinito traduzioni di directory. Dovresti compilare la risorsa su richiesta, non dire che è sbagliata, ma ci sono alcuni trucchi. – StingeyB

7

di Ryan di cui sopra è perfetto, tranne il backend deve essere inizializzato se non è stato già fatto.

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

Sono rimasto bloccato quando le traduzioni restituivano l'hash vuoto finché non ho letto la tua risposta! Grazie – hammady

0

I18n-js funziona perfettamente per me e lo consiglierei. Se usi il suo rewrite branch allora il plugin includerà un file /assets/i18n/filtered.js che emette esattamente ciò che @ ryan-montgomery ha risposto, senza dover fare nulla manualmente.

In questo modo, è possibile utilizzare le stesse traduzioni sul backend con gli helper Rails t(:key) e utilizzando I18n.t('key') in Javascript sul frontend.

5

per rotaie 3 applicazioni che si potrebbe fare così:

creare un file i18n.js.erb e aggiungerlo al tuo application.js. E aggiungi questo pezzo di codice nel file.

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

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

Ho anche ambito le mie traduzioni per non avere un enorme file javascript. Il mio scopo è: javascript.

Spero che aiuti qualcuno!

+0

Questa è la risposta giusta –

+0

Questa soluzione ha due problemi: 1. Nelle impostazioni di produzione sarà sempre uguale perché le risorse sono compilate 2. È necessario cancellare 'tmp/cache' eve tempo di cambiare le traduzioni in yml. – hlcs

2

Un'altra opzione che potrebbe essere utile:

Supponendo che si dispone di un modello di linguaggio (Slug) che contiene tutte le lingue disponibili. Gestisce i casi in cui c'è una traduzione mancante (è sostituito dalla versione internazionale predefinita)

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

views/layout/application.html.erb

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

In te codice javascript, si può tradurre così:

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

Spero che aiuti!

Problemi correlati