¿No se muestran las traducciones del plugin de WordPress? Solucione el problema de las traducciones que faltan
¿Faltan traducciones después de una ejecución de PTC? Cuatro comprobaciones encuentran casi todas las causas. Compruebe que la cadena haya llegado a PTC, que el nombre del archivo .mo coincida con lo que espera WordPress y que el dominio de texto sea coherente en todo su código. Esta guía detalla cada comprobación en el orden en que debe ejecutarlas.
El mismo orden de diagnóstico funciona tanto si ha traducido con PTC (Private Translation Cloud), GlotPress o cualquier otra herramienta basada en gettext. Los modos de fallo son inherentes al pipeline de i18n de WordPress, no a ningún traductor en particular.
Confirme que la cadena ha llegado a PTC
La primera pregunta es si la cadena está en su proyecto de PTC. Si una cadena no se extrajo a su archivo .pot, PTC nunca la vio. El archivo .po no tiene ninguna traducción para ella. El plugin en ejecución muestra la reserva del idioma de origen.
Cómo comprobarlo:
- Abra la cadena afectada en el plugin en ejecución y copie su texto exacto.
- Vaya a su panel de control de PTC, abra la pestaña Translations y busque la cadena.
- Si no está ahí, PTC nunca la recibió.
A continuación se detallan tres causas comunes.
Causa 1: la cadena no está en su archivo POT
wp i18n make-pot solo extrae las cadenas dentro de las funciones de i18n reconocidas. Esto significa __(), _e(), _n(), _x() y las variantes escapadas, con el dominio de texto correcto. Las cadenas dentro del dominio incorrecto se omiten. Las cadenas hardcoded fuera de una función de i18n se omiten.
Vuelva a ejecutar la extracción y verifique que la cadena ahora está en el .pot:
wp i18n make-pot . languages/my-plugin.pot --domain=my-plugin
grep "Save Changes" languages/my-plugin.pot
Si grep devuelve la cadena con un msgid, la extracción funciona. Vuelva a subir el nuevo .pot a PTC y vuelva a traducir. Si grep no devuelve nada, la cadena es hardcoded y no está envuelta en __(). Ese es su error. Envuelva la cadena y vuelva a extraerla.
Causa 2: el texto no está envuelto en una función gettext
Cada cadena localizable en su código necesita un wrapper. Use __(), esc_html__(), _e(), _n() o _x() con el dominio de texto correcto:
__( 'Hello, world!', 'your-plugin' );
Causa 3: las cadenas de JavaScript no se marcaron como localizables
Si su plugin incluye texto traducible en JavaScript:
- En el panel de control de PTC, vaya a Configuración > Archivos monitorizados.
- Edite el archivo de recursos correspondiente y active «Is this a WordPress project with localizable JavaScript?»
Esto le indica a PTC que escanee los archivos de JavaScript en busca de cadenas traducibles. PTC regenera las traducciones y abre un nuevo merge request con los archivos actualizados.
Luego, asegúrese de que WordPress sepa dónde cargar los archivos de traducción .json que produjo PTC. Llame a wp_set_script_translations() con la ruta correcta:
// For plugins
wp_set_script_translations(
'script-handle',
'text-domain',
plugin_dir_path( __FILE__ ) . 'languages'
);
// For themes
wp_set_script_translations(
'script-handle',
'text-domain',
get_template_directory() . '/languages'
);
Esto le indica a WordPress que cargue los archivos .json desde la carpeta de su plugin o tema.
Confirme que WordPress está cargando su archivo .mo
Si la cadena está en PTC y el archivo .mo existe en el directorio languages/ de su plugin pero el plugin renderizado sigue mostrando inglés, WordPress está fallando al cargar el .mo.
Diagnóstico 1: ¿está configurado correctamente el idioma del sitio? Vaya a Ajustes > Generales > Idioma del sitio en wp-admin y confirme que coincide con su idioma de destino. Por ejemplo, configúrelo en «Español» para probar el español. Si el sitio está en inglés, su .mo en español nunca se cargará. Esto no es un error.
Diagnóstico 2: ¿se está ejecutando realmente load_plugin_textdomain()? Añada una línea de depuración temporal:
add_action( 'init', function() {
$loaded = load_plugin_textdomain(
'my-plugin',
false,
dirname( plugin_basename( __FILE__ ) ) . '/languages'
);
error_log( 'my-plugin textdomain loaded: ' . var_export( $loaded, true ) );
} );
Vuelva a cargar una página y compruebe su registro de errores de PHP. loaded: true significa que WordPress encontró y cargó un archivo .mo para el idioma actual. loaded: false significa que no lo hizo. La causa suele ser una discrepancia en el nombre del archivo (consulte la siguiente sección) o una ruta de directorio incorrecta.
Diagnóstico 3: ¿es correcto el momento del hook? load_plugin_textdomain() debe ejecutarse en el hook init. Ese es el hook canónico para que las traducciones se apliquen a las cadenas que se imprimen durante el procesamiento normal de la solicitud.
Diagnóstico 4: ¿las traducciones de la comunidad están sobrescribiendo sus archivos empaquetados? De forma predeterminada, WordPress da prioridad a los archivos de traducción almacenados en /wp-content/languages/. Si su plugin o tema tiene traducciones proporcionadas por la comunidad en WordPress.org, esos archivos pueden sobrescribir los archivos .mo empaquetados con su proyecto. Para evitar esto, use el filtro load_textdomain_mofile para forzar la carga de la ruta de su archivo empaquetado antes de que WordPress compruebe el directorio global. Los proyectos con múltiples dominios de texto (un plugin que integra otro plugin) necesitan que cada dominio se cargue por separado. Cada dominio necesita su propia llamada a load_plugin_textdomain() o load_theme_textdomain().
Asegúrese de que el nombre del archivo MO coincida con el patrón de búsqueda de WordPress
La búsqueda de archivos .mo de WordPress sigue una convención de nomenclatura estricta. Incluso con un solo carácter incorrecto, WordPress recurre silenciosamente al inglés.
La convención depende de dónde coloque el archivo:
| Ubicación | Patrón | Ejemplo |
|---|---|---|
/languages/ del plugin |
{text-domain}-{locale}.mo |
my-plugin-de_DE.mo |
/languages/ del tema |
{locale}.mo |
de_DE.mo |
Directorio global (/wp-content/languages/...) |
{text-domain}-{locale}.mo |
my-theme-de_DE.mo |
Algunos ejemplos prácticos:
my-plugin-es_ES.mopara español (España)my-plugin-fr_FR.mopara francés (Francia)my-plugin-pt_BR.mopara portugués (Brasil)my-plugin-zh_CN.mopara chino (simplificado)my-plugin-ja.mopara japonés (algunos idiomas locales no tienen sufijo de región)
Errores comunes:
- Prefijo del dominio de texto incorrecto. Si el encabezado
Text Domainde su plugin esmy-pluginpero el.mose llamamyplugin-es_ES.mo(sin guion), WordPress no lo encontrará. El prefijo debe coincidir exactamente con el valor deText Domain. - Código de idioma local incorrecto.
es.moen lugar dees_ES.mo. WordPress utiliza códigos de idioma locales regionales.es_ES,es_MXyes_ARson archivos diferentes. Un código de idioma simple solo funciona cuando no existe ningún archivo regional. - Guion frente a guion bajo. Los códigos de idioma local usan guion bajo (
es_ES), nunca guion (es-ES). Esto confunde a los desarrolladores que copian los códigos de idioma local de los encabezadosAccept-Languagedel navegador o de fuentes BCP 47, donde el guion es el estándar. - Directorio incorrecto. El encabezado
Domain Pathdebe apuntar al directorio que contiene sus archivos.mo. SiDomain Pathes/languagesy sus archivos.moestán en/lang/, WordPress no los encontrará.
Compruébelo comparando la lista de archivos que produjo PTC con el idioma local que está usando su sitio:
ls plugins/my-plugin/languages/
# my-plugin-es_ES.mo
# my-plugin-es_ES.po
# my-plugin-fr_FR.mo
# my-plugin-fr_FR.po
Si los nombres parecen correctos pero las traducciones siguen sin cargarse, ejecute el diagnóstico de load_plugin_textdomain() anterior para confirmar que WordPress está encontrando el directorio.
Compruebe que su dominio de texto sea coherente en todo su código
Este es el asesino silencioso. Cada llamada a __(), _e(), _n(), _x() en su código pasa un dominio de texto como su último argumento. Si tan solo una llamada pasa el dominio incorrecto, esa única cadena no se traducirá. Todas las demás cadenas del plugin funcionarán bien.
// Correct - matches the plugin's Text Domain
$correct = __( 'Save Changes', 'my-plugin' );
// Wrong - text domain typo; this string is never translated
$wrong = __( 'Save Changes', 'myplugin' ); // missing hyphen
// Wrong - copy-pasted from another plugin
$wrong = __( 'Save Changes', 'other-plugin' );
// Wrong - WordPress core domain; works for core strings but not yours
$wrong = __( 'Save Changes', 'default' );
Encuentre incoherencias haciendo un grep en su código fuente:
grep -rE "__\(|_e\(|_n\(|_x\(" --include="*.php" .
Fíjese en el último argumento de cada coincidencia. Todos deberían ser el dominio de texto de su plugin. Si encuentra errores tipográficos o de copiar y pegar, corríjalos y vuelva a ejecutar wp i18n make-pot para actualizar el .pot.
Para el código JavaScript que usa @wordpress/i18n, se aplica la misma regla. wp_set_script_translations() en PHP también debe pasar el dominio correspondiente:
wp_set_script_translations( 'my-plugin-editor', 'my-plugin', '...' );
// ^^^^^^^^^^^
// Must match the JS calls
Detecte los mismos problemas antes de publicarlos con AI Visual QA
El ciclo de diagnóstico anterior es reactivo. Falta una traducción y usted se pone a buscar la causa. AI Visual QA de PTC detecta los mismos problemas antes de que se publiquen. Inspecciona el plugin renderizado en cada idioma de destino después de cada actualización de traducción e informa de lo que falta o está mal.
Para una cadena en inglés hardcoded fuera de __() (Causa 1 anterior), AI Visual QA ve la cadena sin traducir en el plugin renderizado. PTC genera un prompt listo para pegar para Cursor o Claude Code para envolver la cadena en __(). Para una discrepancia en el dominio de texto (la comprobación de la sección anterior), ve la cadena sin traducir cuando otras cadenas en la misma pantalla están traducidas, e informa de la incoherencia.
Si aún no ha activado AI Visual QA, consulte el tutorial de temas y plugins de WordPress para su configuración.
Cuando se superan las cuatro comprobaciones y las traducciones siguen sin aparecer
Si ha ejecutado las cuatro comprobaciones y las traducciones siguen sin mostrarse, envíe un correo electrónico al soporte de PTC con:
- El dominio de texto de su plugin.
- Uno de los nombres de archivo
.mo(p. ej.,my-plugin-es_ES.mo). - Una captura de pantalla del panel de control de PTC que muestre la cadena afectada con su traducción.
- La configuración del idioma del sitio en Ajustes > Generales.
La mayoría de los casos de «traducciones que faltan» se reducen a una de las causas anteriores. Los casos límite (versiones específicas de WordPress, resolución de idiomas locales en MultiSite, conflictos con otro plugin de i18n) a veces necesitan una segunda revisión.
Mantenga los futuros lanzamientos sincronizados con la localización continua
Una vez que sus traducciones se carguen correctamente, configure el flujo de trabajo de localización continua para que los futuros lanzamientos se mantengan sincronizados con sus traducciones: automáticamente, en cada push a main.