Guía para traducir temas y plugins de WordPress para desarrolladores

Has llegado aquí buscando cómo traducir el tema o plugin de WordPress que has o estas programando. Cómo desarrollador de plugins y temas te voy a explicar todos los aspectos que he aprendido y que necesitas saber para conseguir que tu tema/plugin este preparado para la traducción.


1 - Preparar el tema/plugin para la traducción
2 - Funciones y cadenas de traducción
3 - Crear el fichero POT
4 - Ficheros .po y .mo
5 - Loco Translate y Poedit

1. Preparar el tema/plugin para la traducción

Para empezar a traducir los textos de un tema o plugin el código debe estar preparado expresamente para la traducción ya desde la fase de desarrollo.

La traducción de textos en WordPress se hace con la función __(). Esta función sirve para buscar la traducción de un texto dado como primer argumento en distintos catálogos de idiomas. Admite un segundo parámetro llamado «Text Domain» que es opcional y sirve para agrupar todos los textos del mismo tema/plugin.

echo  __( 'Hello', 'mi-plugin' ); 

Esta orden mostrará en pantalla ‘Hello’ si el idioma de WordPress es inglés y ‘Hola’ si el idioma establecido es español.

Cada plugin o tema utiliza un valor único como «Text Domain» y sirve para diferenciarse de las traducciones de otros plugins/temas.

Y, aunque no es obligatorio, te recomiendo que la hagas coincidir con el slug del propio plugin o tema. Especialmente si piensas publicarlo en el catálogo público de wordpress.org.

Una vez has escogido un «Text Domain» hay que indicarlo en la configuración.

Si estas creando un tema, editarás el fichero style.css, y añadirás el campo «Text Domain» en la cabecera:

mi-tema/style.css

/*
        Theme Name: Mi tema
        Text Domain: mi-tema
        Tags: translation-ready

*/

Y si estas creando un plugin lo indicarás en la cabecera su fichero principal (el que se llama igual que la carpeta del plugin). Si tu plugin se llama mi-plugin, editarás el fichero mi-plugin/mi-plugin.php.

mi-plugin/mi-plugin.php

<?php
/**
 * Plugin Name: Mi plugin
 * Text Domain: mi-plugin
 * Domain Path: /languages
 *
 */

NOTA El campo «Domain Path» sirve para indicar la carpeta donde colocarás los ficheros de las traducciones (ficheros .pot y .po). Este campo sólo es necesario si quieres utilizar una carpeta diferente de /languages.

Cargar los archivos de idioma

Es importante que sepas que un tema o plugin no carga automáticamente los archivos de idioma. Tienes que cargarlos explícitamente desde el propio código.

Las instrucciones son diferentes para plugins y temas.

En el caso de que estés creando un tema, añade esta instrucción al fichero functions.php:

<?php

load_theme_textdomain( 
	'mi-tema', 
	get_template_directory() . '/languages' 
);

y si estas creando un plugin, añade esta instrucción en el archivo principal.

<?php

load_plugin_textdomain(
	'mi-plugin', 
	false, 
	basename( dirname( __FILE__ ) ) . '/languages' 
);

Cambia mi-tema o mi-plugin por el nombre(slug) del tuyo.

2. Cadenas de traducción

Te he enseñado que la función __() sirve para hacer un texto traducible, pero hay otras funciones:

__()

// cadena original.
echo 'Hello';

// cadena con traducción.
echo  __( 'Hello', 'text-domain' );

Que devuelve la traducción si existe en el idioma configurado.

_e()

// echo de cadena con traducción.
_e( 'Hello', 'text-domain' );

Además de hacer la traducción hace un echo (la muestra) en pantalla.

esc_html__()

// cadena original.
echo '<b>Hello</b>';

// cadena con traducción y escape.
echo '<b>' . esc_html__( 'Hello', 'text-domain' ) . '</b>';

Esta función traduce y escapa el contenido de la cadena. Utilízala siempre que el texto pueda contener etiquetas HTML.

NOTA Para evitar ataques XSS siempre hay que escapar los textos procedentes del usuario. Es más, te recomiendo escapar siempre todos los textos que muestres en pantalla a menos que tengas una buena razón para no hacerlo.

esc_html_e()

// cadena original.
echo 'Hello';

// cadena con traducción y escape.
esc_html_e( 'Hello', 'text-domain' );

Igual que la anterior pero con un echo.

Traducir cadenas con variables

Para traducir textos que tienen variables hay que usar cadenas de formato. Para refrescar las ideas, aquí puedes ver un ejemplo de su uso en PHP:

$formato = 'Hay %d monos en el %s';
echo sprintf($formato, $num, $ubicación);

Las funciones printf() y sprintf() sirven para formatear textos. Y para hacerlos traducibles basta con envolverlos con una de las funciones de traducción que hemos visto.

Aquí puedes ver un ejemplo completo:

// cadena original
printf( 'We deleted %d messages.', $count );

// cadena con traducción
printf( esc_html__( 'We deleted %d messages.', 'text-domain' ), $count );

Cadenas en singular y plural

Tanto en español como en inglés, al utilizar variables con números te encontrarás que la traducción de la frase es distinta si es singular o plural.

Fíjate que la traducción del ejemplo anterior es incorrecta si la variable $count toma el valor 1:

printf( esc_html__( 'Deleted %d messages.', 'text-domain' ), 1 );
// Deleted 1 messages

Para estos casos existe la función _n().

La función _n() sirve para obtener la traducción en singular o plural en base al valor de una variable que se pasa como parámetro.

// Empleo: _n( $single, $plural, $number, $domain )

$count = 1
echo _n('Deleted a message.', 'Deleted %d messages.', $count, 'text-domain');
// Deleted a message

$count = 2
echo _n('Deleted a message.', 'Deleted %d messages.', $count, 'text-domain');
// Deleted 2 messages

Y aquí puedes ver otro ejemplo, más complejo, dónde la función _n() traduce un formato. Luego, el formato traducido es un argumento para la función printf() para que lo complete con el valor de la variable.

printf( 
    esc_html( 
        _n( 'We deleted %d message.', 
            'We deleted %d messages.', 
            $count, 
            'text-domain'  
        ) 
    ), 
    $count 
);

Fíjate que la variable $count se utiliza en dos lugares. Primero para averiguar si el formato es singular o plural, y luego, para sustituir el valor en el formato.

3. El fichero POT

En este punto, el plugin esta terminado y has envuelto todas las cadenas de texto existentes con las funciones de traducción __().

El siguiente paso es generar un fichero que agrupa todas las cadenas y que sirve para facilitar su tarea a los traductores.

WordPress utiliza POT «portable object template» que es un estándar para la traducción en PHP. De forma resumienda, el fichero .pot es un fichero de texto que tiene un apartado por cada texto traducible del tema/plugin.

Así que al utilizar una función de traducción como en este ejemplo:

echo __('Unknown error', 'text-domain');

Encontrarás una referencia a esta cadena dentro del fichero .pot:

123
#: lib/error.c:116
msgid "Unknown error"
msgstr ""

Te explico el formato. Cada entrada esta formada por 3 líneas. Empieza con un comentario que es opcional y, que normalmente indica el archivo y la línea dónde aparece la cadena de texto que necesita traducción.

La segunda línea empieza por la clave msgid y su valor es la cadena de texto que hay que traducir y esta encerrada entre comillas.

La última línea empieza por la clave msgstr y su valor es la traducción que también esta encerrada entre comillas dobles.

Cómo crear el fichero .pot - makepot.php

Existen herramientas para buscar todas las cadenas a traducir dentro del código y meterlas en el fichero pot. Te voy a enseñar como utilizar las herramientas propias de WordPress aunque hay otras.

# Descargar
svn co http://develop.svn.wordpress.org/trunk/tools/

# --------------
# Modo de empleo
#  makepot.php
# --------------
cd tools/i18n/
php makepot.php <target> <directory> <output_file>
  • El target puede ser «wp-plugin» para traducir un plugin o «wp-theme» para traducir un tema.
  • directory es la carpeta dónde esta el tema o el plugin.
  • output_file es el nombre del fichero .pot que va a crear la herramienta, que debe coincidir con el campo «Text Domain», es decir, con el slug del tema o el plugin.

Te pongo unos ejemplos:

# --------------------------
# crear un .pot para un tema
# --------------------------
php makepot.php wp-theme /ruta/ficheros/tema slug-tema.pot

# ----------------------------
# crear un .pot para un plugin
# ----------------------------
php makepot.php wp-plugin /ruta/ficheros/plugin slug-plugin.pot

Coloca el archivo .pot que has generado dentro de la carpeta /languages para que lo utilice un traductor para un idioma.

Traducir un tema/plugin de WordPress.org

Seas o no el autor de un tema o plugin, es la comunidad de WordPress la encargada de realizar todas las traducciones. Existen grupos de trabajo para cada locale (ES, FR…) y de los más activos es el grupo de trabajo de español.

Si quieres traducir tu propio tema o plugin tienes que solicitar la traducción en el slack de WordPress en español o convertirte en un traductor. Existen varios niveles para los traductores de cada traducción (locale), de entre los cuales te interesan estos dos:

  • «Translation Contributor» a este nivel puede acceder cualquier usuario registrado en WordPress.
    Puedes sugerir la traducción de cada cadena desde la propia página de tu plugin en wordpress.org que luego tiene que aprobar un editor.
    No necesitas permisos ni nada especial, realizas la traducción de tus cadenas y esperas a la aprobación de un editor.

  • «Project Translation Editor» (PTE) es aquel traductor responsable de las traducciones de un plugin/tema concreto.
    Tienes que seguir las normas de la comunidad para convertirte en traductor PTE de tu propio proyecto y pedir instrucciones en el foro de #traductores-plugins o #traductores-temas del Slack de WordPress en español.

Normas de traducción

En estos enlaces encontrarás las normas que deben seguir los textos de tus traducciones:

Guía para traductores de español de España - Donde encontrarás las normas básicas para realizar correctamente una traducción. Por ejemplo, hay que utilizar el español informal, utilizar el termino “sitio” en lugar de “blog”…

Glosario de traducciones del núcleo de WordPress en español - Es un listado de términos comunes y la traducción recomendada. Por ejemplo, la traducción recomendada para “About” es “Acerca de”.

Por experiencia, cuanto más popular sea tu plugin o tema antes conseguirás la traducción. En cualquier caso, si estás muy interesado en la traducción consulta en el slack de WordPress.

Generar el fichero PO


Los siguientes pasos son sólo necesarios si quieres incluir las plantillas de traducciones junto a tu plugin o tema. Recuerda que si el tema/plugin esta en wordpress.org es obligado que las traducciones las realice la comunidad.

Hacer tu mismo las traducciones te puede interesar para facilitar la tarea al traductor (tardará menos en aprobar la traducción), o si estás distribuyendo el código en un market de pago o por ti mismo.

Cada una de las traducciones para un idioma o locale estará en un nuevo fichero que tiene la extensión .po. Los ficheros pot y po usan el mismo formato. Básicamente, el fichero .po es igual al .pot pero incluye las traducciones.

Para crear el fichero .po, sólo copia el .pot que generaste en el paso anterior a un nuevo fichero con el nombre slug-{locale}.po

# cp slug.pot slug-es_ES.po 

Ahora puedes abrir el fichero .po con tu editor y traducir cada una de las cadenas. Aquí puedes ver un ejemplo:

#: lib/error.c:116
msgid "Unknown error"
msgstr "Error desconocido"

Generar el fichero MO


El último paso es crear el fichero .mo que es un binario generado a partir del .po y que utiliza WordPress internamente.

Puedes utilizar la consola de linux para crear el fichero .mo

msgfmt -o <output>.mo <input>.po

Traducir con plugins

Si quieres evitar usar la consola tienes 2 alternativas:

  • Loco Translate - Este plugin te sirve tanto traducir cadenas como para generar los fichero .pot y .po. Sobre todo, lo utilizan los maquetadores para traducir temas de pago.
  • Poedit - Es una aplicación de escritorio para cualquier plataforma. La versión básica es gratuita y al igual que Loco Translate puede generar los ficheros .pot y .po.

He creado esta guía para aquellos que están subiendo su primer plugin o tema a WordPress. ¡Espero que te sea de ayuda!. Y no dudes en comentar cualquier cosa.

César Maeso


Creative Commons License

Esta obra está bajo una licencia de Creative
Commons Reconocimiento-NoComercial-CompartirIgual
4.0 Internacional
.