Internacionalizar un plugin significa prepararlo para que pueda ser traducido a diferentes idiomas, es un proceso necesario, ya que, al usar un plugin, se espera poder cambiar los textos, o traducirlos a otros idiomas de manera simple.
1- Internacionalizar la metadata del plugin
Dentro de la definición de la metadata del plugin, tienes que tener en cuenta los siguientes datos:
- Text Domain: Dominio de texto, es una cadena única que identifica a nuestro plugin y será usada por las funciones de traducción, usualmente será el nombre del archivo principal.
- Domain Path: Carpeta en donde se localiza los archivos de traducción.
El siguiente código muestra la metadata en inglés de un plugin de ejemplo:
<?php
/*
* Plugin Name: DCMS Simple Author Bio
* Plugin URI: https://decodecms.com
* Description: This plugins shows the author biography in articles
* Version: 1.0.0
* Author: Jhon Marreros Guzmán
* Author URI: https://decodecms.com
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
* Text Domain: dcms-simple-author-bio
* Domain Path: /languages
*/
Esta información nos servirá para traducir la metada del Nombre del plugin y de la Descripción, cuando listamos los plugins instalados en nuestro sitio web veremos la traducción en español.

Te preguntarás ¿en dónde coloco la traducción de la descripción y el nombre del plugin?, estará los archivos de idiomas que generaremos en los siguientes pasos, sigue leyendo…
2- Cadenas de texto traducibles en código
Definida la cadena de “dominio de texto”, la usaremos en las funciones de traducción. Recuerda usar funciones de traducción desde el inicio que empiezas a codificar un plugin.
Las funciones que usualmente se usan son:
- __(): Marca el texto como una cadena traducible y lo retorna para su uso en PHP, tener en cuenta que se usa doble guion bajo, como segundo parámetro acepta el dominio de texto. Por ejemplo :
$cad = __(‘Cadena de texto a traducir’,’dominio-texto’);
- _e(): Similar a la función anterior, la única diferencia es que imprime el texto directamente, similar a echo de PHP.
_e(‘Cadena de texto a traducir’,dominio-texto’);
Existen otras variantes de estas funciones, por ejemplo:
- esc_attr__(): Similar a esc_attr() pero con traducción, escapa caracteres que no pueden ser usados como atributos..
- esc_attr_e(): Similar a la función anterior pero imprimiendo el resultado.
- esc_html__(): Similar a esc_html(), escapa código HTML para mostrarlo como código.
- esc_html_e(): Similar a la anterior pero imprimiendo el resultado.
- _x(): Para usar el mismo texto varias veces pero con un parámetro adicional de contexto.
- _n(): Para diferenciar entre cadenas en singular y plural.
Existen otras funciones que son combinaciones de estas dos últimas por ejemplo: esc_html_x(), o _nx()
También es posible usar placeholders dentro de las funciones de traducción, por ejemplo:
printf( __(‘The name of your blog is %s’, ‘dominio-texto’), get_bloginfo(‘name’) );
Si necesitas traducir algún texto dentro de javascript puedes combinar estas funciones con wp_localize_script() , en este artículo te explico el uso de esta función.
3- Cargando el texto de dominio
Adicional a los metadatos del plugin, para que las funciones de traducción encuentren los archivos de traducción, es necesario indicar el texto de dominio y la ruta de los archivos de traducción a través de la función load_plugin_textdomain, en algún hook como inti o plugins_loaded, por ejemplo usando los mismos valores que usamos en el punto 1:
add_action('plugins_loaded', 'dcms_plugin_load_textdomain');
function dcms_plugin_load_textdomain() {
$text_domain = 'dcms-simple-author-bio';
$path_languages = basename(dirname(__FILE__)).'/languages/';
load_plugin_textdomain($text_domain, false, $path_languages );
}
En el código anterior:
- Usamos la función load_plugin_textdomain con el segundo parámetro a false debido a que está obsoleto.
- Tener en cuenta que el parámetro para la ruta del plugin ($path_languages) debe ser una ruta relativa en base a la carpeta en donde se encuentra el plugin.
- El nombre de los archivos de traducción será de la forma :
{texto-dominio}-{idioma}.mo
y estarán dentro de la carpeta languages de nuestro plugin, por ejemplo:
languages/dcms-simple-author-bio-es_ES.mo
4- Archivos .pot .po y .mo
Como te habrás dado cuenta usamos el idioma inglés como base para las cadenas de nuestros plugin, ahora buscaremos crear los archivos de traducción en base a esos textos.
- pot: Este es el archivo principal, debería ser incluido también en la carpeta languages de nuestro plugin, es un archivo de plantilla genérico, sin traducciones, y es el archivo que buscaremos crear como primer paso, este archivo contiene todas las cadenas de texto que hemos usado en las funciones de traducción.
- po: Este archivo es un archivo generado en base al archivo .pot, adicional a los textos de plantilla tiene también sus traducciones, es decir hay un archivo .po por cada idioma que queremos traducir, este archivo esta en un formato legible y se puede leer con un editor de textos, WordPress no usa este archivo.
- mo: Este archivo tiene las mismas características que el archivo .po, sin embargo esta en un formato que WordPress usará, no es legible si abrimos este archivo en un editor de textos. Este archivo se crea automáticamente cuando se edita el archivo .po con alguna herramienta como Poedit
5- Creando los archivos de traducción
Una vez tenemos todos los elementos anteriores configurados, finalmente vamos a crear los archivos de traducción.
Primero necesitamos crear la plantilla o archivo .pot el cual tendrá todas las cadenas que hemos preparado para traducir, para crear este archivo podemos usar una aplicación como Poedit o Easy PO, y escanear nuestro código, sin embargo estas aplicaciones posiblemente no me reconozcan las cadenas de las metadata del plugin que hemos visto en el paso 1.
Para la creación de nuestro archivo .pot usaremos las herramientas de internacionalización de WordPress : wp-i18n-tools
Sigue los siguientes pasos:
- Descarga el .zip de herramientas de internacionalización
- Extrae el contenido directamente en la carpeta wp-includes de tu sitio WordPress de desarrollo.
- Asegúrate de tener instalado PHP para ser ejecutado desde la línea de comandos.
- Usa la aplicación de lína de comandos para ejecutar makepot.php , con la siguiente sintaxis :
php makepot.php TIPO DIRECTORIO_PLUGIN ARCHIVO_SALIDA
En donde el TIPO puede ser wp-plugin o wp-theme
- Por ejemplo en base a la sintaxis anterior:
php wp-includes/makepot.php wp-plugin wp-content/plugins/MI_PLUGIN/ wp-content/plugins/MI_PLUGIN/languages/MI_PLUGIN.pot
- En el código anterior se asume que nos encontramos en la carpeta raíz de nuestros WordPress, debemos reemplazar MI_PLUGIN por el nombre de nuestro plugin.
- Finalmente una vez tienes el archivo .pot generado dentro de la carpeta languages, puedes entonces usar Poedit o Easy Po para generar los archivos .po y mo.
- No olvidar cambiar de nombre a los archivos .mo generados de acuerdo al punto 3 tratado anteriormente.
En la siguiente imagen se puede observar la traducción de un archivo .po generado desde el archivo .pot

¿Aún con dudas?, en el siguiente video se explica cómo internacionalizar un plugin de manera detallada.
Buen artículo, gracias.
Como le haces una vez que ya tienes el archivo POT generado para actualizar el catálogo de los archivos PO sin tener que abrir el archivo por cada traducción?
Si usas Poedit tendrías que hacerlo por cada idioma, abrir el pot y guardarlo para cada idioma como pot.
Disculpa me puedes regalar una copia o publicar un archivo base pot para usar en cualquier plugin. Esto por que no me funciono el makepot.php, muchas gracias.
Hola, la puedes descargar desde este enlace: https://github.com/wp-mirrors/wp-i18n-tools , en el artículo igual lo indico, revisa el video para que sepas cómo usarla.