2011-07-22 16 views
5

¿Hay alguna manera de anidar las búsquedas de traducción? Algo como esto:Rails I18n claves de traducción anidadas

en: 
    uh_oh: 'Uh Oh!' 
    error1: :'uh_oh' + ' There was a big error!' 
    error2: :'uh_oh' + ' There was another big error!' 
I18n.t('error1') #=> 'Uh Oh! There was a big error!' 
I18n.t('error2') #=> 'Uh Oh! There was another big error!' 

he intentado un montón de variaciones de esto, y también lo intentó con un archivo de traducción de rubíes en lugar de YAML. Tenga en cuenta que este hace trabajo:

en: 
    uh_oh: 'Uh Oh!' 
    error1: :'uh_oh' 
I18n.t('error1') #=> 'Uh Oh!' 

Pero si puedo añadir texto adicional a error1, uh_oh no se traducen.

Básicamente quiero evitar tener que pasar siempre en términos comunes, como esto:

en: 
    uh_oh: 'Uh Oh!' 
    error1: '%{uh_oh} There was a big error!' 
I18n.t('error1', {uh_oh: I18n.t('uh_oh')}) 

Para conocer los términos comunes como uh_oh, la interpolación es la misma para cada llamada a error1 (y cualquier otro clave que usa uh_oh), por lo que no tiene sentido pasar una cadena para interpolar. Que sería más fácil hacer lo siguiente en su lugar y tienen la traducción error1 hacerse cargo de la traducción en clave común:

I18n.t('error1') 

Respuesta

4

No voy a responder a su pregunta (no creo que es posible con la i18n joya, pero podría estar equivocado). Voy a decir que no debes tomar este enfoque y darte un enlace [1] como fondo. Como desarrolladores, es natural ver patrones y extraer código común para mantener las cosas SECAS. Esto es un paso demasiado lejos cuando se trata de múltiples idiomas, ya que impide las traducciones adecuadas. No todos los idiomas siguen la misma estructura de oraciones que el inglés y lo que está sustituyendo puede tener que cambiar para coincidir con el resto de la oración.

En un sitio donde trabajo tenemos este problema con el francés. Tenemos oraciones que incluyen un nombre de ubicación y esto es sencillo en inglés. La propiedad "% {location_name}" funciona independientemente del nombre de la ubicación. Sin embargo, en francés, necesita diferentes estructuras dependiendo de si la ubicación es una ciudad, una provincia, una región, y si el nombre comienza con una vocal o no.

[1] http://www.multilingual.com/articleDetail.php?id=594

+0

Sé lo que quieres decir sobre las diferentes estructuras de oraciones y reglas de gramática. Pero obtener el valor de una variable, ya sea desde un par clave/valor de traducción (como pregunto) o al pasarlo explícitamente, no cambia la forma en que se estructura la oración en el archivo de cada idioma. –

+0

Cierto, aún así debes tener cuidado con el género. Creo que necesitarías escribir tu propio ayudante para esto. es decir, Haga su teclas algo como: 'clave: "!! some.key foo bar"' Donde su envoltorio I18n.t sería conseguir la llave, y luego ir buscar el some.key y sustituirla en – chrismcg

+0

Usted podría hacer esto como un back-end i18n personalizado también. – chrismcg

0

La razón por la que puede hacer la "I18n.t ('error1')" sustitución por sí mismo, porque eso es un caso especial de que el I18n llama un "enlace simbólico".

Por desgracia, no hará nada más que una única sustitución completa.

Veo dos soluciones para resolver este problema. La primera fue postprocesar la salida de I18n, lo que podría ser difícil cuando no se tiene control total sobre cuándo se llama a I18n y si el consumo de los mensajes traducidos puede extenderse (como en Rails). La mejor opción sería anular la función I18n.t.

Otra opción es aprovechar la capacidad de almacenar una lambda en el back-end I18n. Desafortunadamente, esto significa que no puede almacenar la traducción combinada en el archivo YAML, ya que solo admite cadenas básicas.

A modo de ejemplo, en el YAML traducción que podría tener cualquiera de los mensajes de error:

en: 
    error: "There was a big error [%{arg}]!" 

y ahora queremos llamarlo con la traducción de uh_oh antes. necesitamos almacenar la traducción en combinación con uh_oh en el back-end I18n:

translam = lambda { |key,opts| "Uh Oh! #{I18n.t(opts[:for],opts)}" } 
I18n.backend.store_translations(:en,:uh_oh => translam) 

Ahora podemos traducir "uh_oh" y darle el error queremos traducir, además de los argumentos que pueden necesitar:

I18n.t(:uh_oh, for: :error, arg: 42)) #=> 'Uh Oh! There was a big error [42]!' 
Cuestiones relacionadas