2010-04-23 18 views
52

Por lo tanto, tenemos una aplicación Rails 2.3.5 existente que no admite la Internacionalización en absoluto. Ahora, estoy familiarizado con Rails I18n, pero tenemos MUCHAS cadenas de salida dentro de /javascripts/. No soy un gran admirador de este enfoque, pero desafortunadamente es demasiado tarde para solucionarlo ahora.Rails: ¿internacionalización de cadenas de Javascript?

¿Cómo podemos internacionalizar cadenas almacenadas en archivos JS en una aplicación de Rails? Rails ni siquiera sirve los archivos JS ...

Estoy pensando que siempre podría hacer que la aplicación Rails sirva los archivos JS, pero parece bastante asqueroso. ¿Hay complementos para hacer esto?

Respuesta

88

Por qué no algo tan simple como:

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

Luego, en JS que puede hacer cosas como:

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

he envuelto en una mina de ayudante de aplicación.

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

Entonces mi llamada en mi application.html.erb se ve así:

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

Esto le permite evitar tener que conocer la localización actual en JavaScript.

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

O

I18n.alpha.bravo; 
+7

Funciona perfecto, gracias. También implementé este método 't' para que sea más railsish. https://gist.github.com/6a3f1b3a4cf8de889e34 't (" products.price ");' – Oleander

+6

Acabo de pasar un día tratando de hacer que i18n-js funcione ... ¡su solución es mucho más simple y funciona de inmediato! – Emmanuel

+0

De hecho, funciona perfecto. ¿Alguna sugerencia sobre cómo obtener solo una parte del archivo en el javascript? ¿O separar las traducciones de javascript en un archivo diferente? Porque ahora todas las traducciones están incluidas cuando solo necesito 2 oraciones. – rept

2

Babilu es un complemento de Rails que hace esto por usted.

1

solución Ryan es brillante. Pero para que no incluya el archivo completo se debe utilizar: @translations[I18n.locale].with_indifferent_access["alpha"] en lugar de I18n.backend.send(:translations)["alpha"]

5

Por qué no simplemente esto en su archivo Javascript:

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

Para que esto funcione, debe agregar a su .erb Javascript extensión del archivo

También podría necesitar agregar la siguiente línea en la parte superior de su archivo Javascript si no está usando ruby> = 2.0.

<%# encoding: utf-8 %> 

Ver el último comentario de la respuesta aceptada en este hilo para más información: solución Encoding issues in javascript files using rails asset pipeline

+4

Una gran razón por la que esto será difícil es la precompilación de activos. Cuando el activo se precompila, el javascript se colocará en el directorio público con su valor predeterminado traducciones de directorio. Habría que hacer ese activo compilar bajo demanda. No es que esté mal, pero hay algunas definitivamente trampas. – StingeyB

7

de Ryan anterior es perfecto, excepto el backend necesita ser inicializado si no ha sido ya.

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

me he quedado atrapado en traducciones regresaba de hash vacío hasta que leí su respuesta! Gracias – hammady

0

I18n-js funciona muy bien para mí y lo recomendaría. Si usa su rewrite branch, el complemento incluirá un archivo /assets/i18n/filtered.js que arroja exactamente lo que contestó @ ryan-montgomery, sin tener que hacer nada manualmente.

De esta manera, puede usar las mismas traducciones en el servidor con Rails helpers t(:key) y utilizando I18n.t('key') en Javascript en la interfaz.

5

para carriles 3 aplicaciones que podría hacer esto:

crear un archivo i18n.js.erb y añadirlo a su application.js. Y agregue este fragmento de código en el archivo.

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

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

También hago un alcance de mis traducciones para no tener un gran archivo javascript. Mi alcance es: javascript.

espero que ayude a alguien!

+0

Esta es la respuesta correcta en realidad –

+0

Esta solución tiene dos problemas: 1. En la producción local siempre será el mismo porque los activos compilados 2. Es necesario borrar '/ tmp cache' víspera Hora en que cambia las traducciones en yml. – hlcs

2

Otra opción que podría ser útil:

Suponiendo que usted tiene un modelo de lenguaje (babosa) que contiene todos los idiomas disponibles. Maneja los casos en los que hay una traducción que falta (es reemplazado por la versión local predeterminada)

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

vistas/diseño/application.html.erb

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

En que el código Javascript, puede traducir así:

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

¡Espero que ayude!

Cuestiones relacionadas