Hablemos de los plurales en la internacionalización de plugins

Publicada en WordPress.

Mira nuestro vídeo

Existe una versión mejor de tu web

Comparte este artículo

Hace un par de semanas publicamos nuestra entrevista con Caspar Hübinger, en la que hablamos en profundidad sobre el tema de la internacionalización de WordPress. Supongo que a estas alturas de la película ya sabes qué es, pero no está de más recordarlo:

La internacionalización es el proceso de desarrollo de un plugin por el cual se permite su fácil traducción a otros idiomas. La localización es el proceso siguiente en el que se traduce de forma efectiva la internacionalización del plugin. (…)

[La internacionalización es importante] porque WordPress se usa en todo el mundo y, por lo tanto, es una buena idea dejar el código preparado de tal forma que se pueda traducir fácilmente. Como desarrollador, puedes no tener el tiempo para ofrecer dichas traducciones; quizás ni siquiera conozcas la lengua en cuestión. Pero cualquier desarrollador puede internacionalizar correctamente su plugin para que sean otros los que lo traduzcan, sin necesidad de modificar el código fuente.

Internacionalización en el Codex de WordPress

Conseguir el máximo número de clientes posibles debería ser tu objetivo como empresa. Para lograr más usuarios, la internacionalización es una pieza clave. Es por ello que deberías esforzarte por escribir código que sea internacionalizable. Por pequeño, sencillo o estúpido que sea el código que estés escribiendo ahora mismo, dejarlo preparado para que en el futuro se pueda traducir no cuesta nada, y los beneficios que ello conlleva son enormes. No sólo para ti (más lenguas implica, como te digo, abarcar una base de usuarios mayor), sino también para tus usuarios, los cuales agradecerán poder usar tu trabajo en su idioma.

De todas formas, mi objetivo hoy no es hablar de las bondades de la internacionalización (i18n) ni convencerte de que lo hagas. De hecho, voy a suponer que ya lo estás haciendo. El objetivo de esta entrada es hablar sobre la i18n de plurales y plantear mis dudas «en voz alta».

Internacionalización de plurales

Supongamos que queremos escribir un texto por pantalla del tipo «Se han eliminado x ficheros». Fíjate que en español, esta frase tiene dos formas posibles:

  • Singular. Cuando hablamos de un único elemento (en este caso, de un único fichero), en español se usa la forma singular: Se ha eliminado 1 fichero.
  • Plural. Cuando hay cualquier otro número (2, 3, 4, … o incluso 0), se usa la forma plural: Se han eliminado 3 ficheros.

Aunque ambas frases son muy parecidas, existen pequeñas diferencias. Por un lado está el número de elementos (el cual suele estar definido en una variable) y por otro lado está la frase que hay que usar (la cual depende, precisamente, del número de elementos).

Traducción de plurales en español
Cuando traducimos «plurales», traducimos las versiones singular y plural a la vez, como un todo. Fíjate que el español es como el inglés: tenemos una forma singular para un único elemento y una forma para cualquier otra cantidad (0, 2, 3, …)

Como estamos partiendo de la base que sabes cómo hacer que tu plugin sea traducible correctamente, doy por sentado que no implementarías esta función usando un bloque if/else, sino que usarías las funciones de internacionalización que tocan. De hecho, necesitaremos usar dos funciones diferentes:

  • _n() es la función de la librería gettext que se encarga de seleccionar la frase que toca según el número de elementos que tenemos. Esta función tiene tres parámetros:
    • La versión singular de la frase.
    • La versión plural de la frase.
    • El número de elementos (los cuales sirven para elegir una versión de la frase u otra).
  • printf() es la función que sustituye un placeholder dentro de la frase por el número concreto de elementos que tenemos.

Pues bien, el ejemplo anterior quedaría así:

printf(
  _n( '%d file deleted.', '%d files deleted.', $count ),
  $count
);

Fíjate que la variable $count aparece dos veces en la instrucción anterior. La primera vez es un parámetro de _n y sirve para seleccionar la frase que toca. La segunda vez es un argumento de la función printf es para sustituir el placeholder (%d) resultado de la primera invocación por el valor concreto de $count. Creo que expresándolo de la siguiente forma se entiende mejor:

$sentence = _n( '%d file deleted.', '%d files deleted.', $count );
printf( $sentence, $count );

Lo más importante cuando traducimos plurales es recordar que estamos traduciendo un «concepto variable». Me explico: en este ejemplo, el concepto que queremos expresar es que se ha eliminado un cierto número de ficheros. Ahora bien, cuando intentamos escribir este concepto en una frase concreta, nos damos cuenta que en inglés tenemos dos formas de hacerlo: la forma singular (cuando se trata de un único fichero) y la fórmula plural (para cualquier otra cantidad). Esto en español es igual, así que es fácil pensar que estamos traduciendo la frase singular por un lado y la frase plural por otro…

Pero en otros idiomas no es así: hay idiomas en los que existen múltiples formas plurales y $sentence puede tener 3, 4, 5 o ¡incluso 6 valores! Así que los traductores de esos idiomas no traducen la frase singular por un lado y la plural por el otro, sino que traducen el «concepto» generando tantas frases como su idioma requiera.

Traducciones al ruso
Existen idiomas, como por ejemplo el ruso, que no tienen un «singular» y un «plural» como el que tenemos en español o inglés. En lugar de eso, tienen varias formas según la cantidad de elementos involucrados. En estos casos, no se traducen literalmente las frases «singular» y «plural» del inglés, sino que, simplemente, se generan las frases que el idioma requiera.

No me gusta el singular con la cifra 1

En nuestra última entrevista, Caspar compartió un pequeño test con el que probar qué tan buenos somos a la hora de internacionalizar nuestros plugins. Tienes bastantes preguntas de respuesta múltiple y todas las respuestas tienen una explicación asociada explicando por qué son correctas o incorrectas. Una de las preguntas era la siguiente:

Which of these is the correct way to use the single/plural _n() function?

  1. printf( _n( 'One person has seen this post.', '%d people have seen this post.', $view_count ), $view_count );
  2. printf( _n( '%d person has seen this post.', '%d people have seen this post.', $view_count ), $view_count );

Ninguna de las dos opciones está «mal», aunque según las respuestas, sólo la segunda es correcta. ¿Qué tiene de malo la primera opción? Veamos lo que nos dice el test:

Escribir «One» en la forma singular es problemático. Nosotros siempre usamos el placeholder en las formas singular y plural. Algunos idiomas (como el ruso) tienen múltiples plurales que requieren la flexibilidad de usar un placeholder de forma explícita en la forma singular.

En otras palabras, parece ser que en ruso (y, por favor, corregidme si me equivoco), se escribe igual «1 persona» (1 человек) que «321 personas» (321 человек), ya que lo importante aquí* es que el número acaba con la cifra «1», a diferencia del inglés o el español, donde lo importante es que sea el 1. Y por eso la recomendación es que siempre usemos el placeholder.

* Quizás la regla es otra, pero para entendernos ya nos vale.

Por desgracia, discrepo con la solución «oficial». Personalmente, el estilo de «One person has seen this post» o, su versión en español, «Una persona ha visto esta entrada«, es muchísimo mejor que la contrapartida numérica «1 person has seen this post» (o «1 persona ha visto esta entrada«). De hecho, creo que si existe esa pregunta en su test es porque muchos desarrolladores opinan como yo y consideran que la forma textual es más bonita que meter el número 1 en la frase.

El problema… ¿de verdad es un problema?

La respuesta oficial nos dice que usar «One» en la oración es problemático ya que, como hemos visto, hay idiomas en que la frase que usamos para «One» se usa también para otras cantidades. Pero yo no estoy de acuerdo. Por ejemplo, las siguientes frases en inglés:

  • One person has seen this post.
  • %d people have seen this post.

las podemos traducir literalmente al español de la siguiente forma:

  • Una persona ha visto esta entrada.
  • %d personas han visto esta entrada.

y todo funcionaría correctamente. Quizás estés pensando que «claro, esto funciona bien porque ya hemos visto que el español y el inglés entienden los singulares y los plurales igual». Y, efectivamente, la traducción funciona porque hemos podido traducir literalmente la frase singular por un lado y la plural por otro.

¿Qué hubiera pasado si el español fuera como el ruso y la primera frase se usase para más cantidades, además de «1»? Pues no hubiera pasado nada… siempre que lo hubiéramos tenido en cuenta.

Recordemos que estamos traduciendo un «concepto»: en este caso, cuánta gente ha visto una cierta entrada. Si nuestro idioma objetivo no permite hacer la traducción literal de «One person» por «Una persona» porque, insisto, la frase puede usarse con otras cantidades diferentes de «un/una», pues simplemente creamos una traducción que incluya el placeholder y listo:

  • %d persona ha visto esta entrada.
  • %d personas han visto esta entrada.

Este par de frases alternativas son una traducción igualmente válida del par de frases originales en inglés. Ahora, en lugar de escribir explícitamente «Una persona», lo dejamos con un placeholder del tipo %d.

Fíjate que las dos soluciones (traducir «One» por «Uno» o traducirlo por %d) funcionan correctamente. La internacionalización es un proceso que funciona en dos pasos: (a) seleccionar la frase adecuada y (b) sustituir los placeholders con printf. Si la frase singular la hemos traducido como «Una persona ha visto esta entrada», no tendrá placeholder y la función printf la dejará tal cual. Si, por otro lado, sí tenía dicho placeholder, el printf sustituiría el %d por 1 dejando como resultado la oración «1 persona ha visto esta entrada».

Así pues, está claro que aunque partamos de una versión original en inglés que no incluye el placeholder, podemos llegar a una solución que funcione en cualquier idioma. Lo que hay que hacer en estos casos es educar al traductor para que (a) entienda que la traducción consta de dos pasos (selección de la frase y sustitución de placeholders) y (b) que si su idioma necesita un placeholder en la forma singular, que lo pongan incluso cuando la versión original no lo incluía.

Y es que, a fin de cuentas, a los traductores profesionales se les llama «intérpretes» por algún motivo, ¿no? Una buena traducción no es un calco exacto del idioma original (inglés), sino que implica una interpretación y adaptación al idioma destino. Así que yo propongo que añadir el placeholder forme parte de esa interpretación y adaptación.

Y tú, ¿qué opinas?

Imagen destacada de Clark Young.</p>

Deja una respuesta

No publicaremos tu correo electrónico. Los campos obligatorios están marcados con: •

He leído y acepto la Política de privacidad de Nelio Software

Al marcar la casilla de aceptación estás dando tu legítimo consentimiento para que tu información personal se almacene en SiteGround y sea usada por Nelio Software con el propósito único de publicar aquí este comentario. Contáctanos para corregir, limitar, eliminar o acceder a tu información.