2009-11-20 19 views
11

En php (o tal vez gettext en general), ¿qué hace gettext cuando ve una variable de contenido dinámico?¿Cómo maneja gettext el contenido dinámico?

Tengo 2 casos en mente.

1) Digamos que tengo <?=$user1?> poked John <?=$user2?>. Quizás en algún idioma el orden de las palabras sea diferente. ¿Cómo maneja gettext eso? (No, no estoy compilando Facebook, eso fue solo un ejemplo)

2) Digamos que almaceno algunas categorías en una base de datos. Raramente, pero se almacenan en una base de datos. ¿Qué pasaría si lo hago <?php echo gettext($data['name']); ?>? Me gustaría que los traductores también traduzcan esos nombres de categoría, pero ¿tiene que hacerse en la base de datos?

Gracias

+1

Los lectores de esta pregunta también pueden estar interesados ​​en "¿Cómo especificar las variables ordenadas en los archivos gettext .po?": Http://stackoverflow.com/questions/13979962/how-to -specify-ordered-variables-in-gettext-po-files – Ryan

Respuesta

19

Su mejor opción es utilizar la función spritf(). Luego usaría la notación printf para manejar contenido dinámico en sus cadenas. Aquí es una función que encontré en aquí hace un tiempo para manejar esto fácilmente para usted:

function translate() 
{ 
    $args = func_get_args(); 
    $num = func_num_args(); 
    $args[0] = gettext($args[0]); 

    if($num <= 1) 
     return $args[0]; 

    return call_user_func_array('sprintf', $args); 

} 

Ahora por ejemplo 1, que se quiere cambiar la cadena a:

%s poked %s 

¿Qué lo haría de entrada en la función de traducir() así:

<?php echo translate('%s poked %s', $user1, $user2); ?> 

Se podría analizar toda translate() funciones con poEdit. y luego traduzca la cadena "% s poked% s" en el idioma que desee, sin modificar los % s marcadores de posición de cadena. Aquellos obtendrían reemplazan a la salida por la función translate() con user1 y user2 respectivamente. Puede leer más sobre sprintf() en el Manual de PHP para usos más avanzados.

Para la edición n. ° 2. Debería crear un archivo estático que poEdit podría analizar con los nombres de las categorías. Por ejemplo "misctranslations.php":

<?php 

_('Cars'); 
_('Trains'); 
_('Airplanes'); 

Luego tienen misctranslations.php poEdit parse. Luego, podría generar la traducción del nombre de categoría usando <?php echo gettext($data['name']); ?>

+4

El caso 1 se puede manejar más fácilmente: ' '. No necesita una función adicional y Poedit aún analizará la cadena como cualquier otra. – DanMan

+1

Si está traduciendo "% s poked% s", ¿cómo puede cambiar los nombres de los dos usuarios cuando ambos están marcados con el mismo marcador de posición? En algunos idiomas, el sujeto va antes que el objeto. – bdsl

4

Para construir un poco sobre lo que dijo Mark ... el único problema con la solución anterior es que la lista estática debe mantenerse siempre a mano y si agrega una nueva cadena antes que las demás o cambia por completo una existente, el soft que usa para traducir podría confundir las nuevas cadenas y podría perder algunas traducciones.

realidad estoy escribiendo un artículo sobre esto (demasiado poco tiempo para terminarlo en cualquier momento pronto!) Pero mi respuesta propuesta es algo como esto:

Gettext le permite almacenar el número de línea que la cadena aparece en el código dentro del archivo .po Si cambia la cadena por completo, el editor de .po sabrá que la cadena no es nueva, pero es antigua (gracias al número de línea).

Mi solución a esto es escribir un script que lea la base de datos y cree un archivo estático con todas las cadenas gettext. La gran diferencia para la solución de Mark es tener la clave principal (llamémoslo ID) en la base de datos que coincida con el número de línea en el nuevo archivo. En ese caso, si cambia por completo una traducción original, las líneas siguen siendo las mismas y su traductor suave reconocerá las cadenas.

Por supuesto que podría haber editores .po más nuevos y más inteligentes, pero al menos si el suyo le está dando problemas con cadenas más nuevas, entonces esto los resolverá.

Mis 2 centavos.

1

@Julian

Creo que su enfoque no funcionaría bien en la práctica. Imagina que mueves alguna función a través del código. El número de línea será diferente, también el nombre del archivo podría ser diferente.

Creo que la única forma inteligente de gestionar el cambio de identificadores de traducción sería tratar de encontrar identificadores similares en su archivo .po. El editor podría mostrar una sugerencia para fusionar el nuevo texto de traducción con el existente, si son muy similares y no hay una cadena de traducción en el número de línea guardado en su código.

1

Si tiene algún lugar en su código: <?=sprintf(_('%s poked %s'), $user1, $user2)?> y uno de sus idiomas necesita cambiar los argumentos, es muy simple. Simplemente traduzca su código así: msgid "%s poked %s" msgstr "%2$s translation_of_poked %1$s"

Cuestiones relacionadas