PTC

Internacionalización de WordPress: Cómo traducir temas y plugins

Prepare su tema o plugin de WordPress para la traducción. Esta guía cubre los dominios de texto, las funciones gettext, la generación de POT y el mecanismo de carga que muestra las traducciones a los usuarios. A continuación, PTC (Private Translation Cloud) traduce los archivos de recursos y realiza una revisión visual de la traducción del tema o plugin renderizado en cada idioma.

Esta guía es para los desarrolladores que escriben el código. Si ya tiene un archivo POT o PO y solo necesita traducirlo, diríjase a la página de archivos PO para conocer el flujo de trabajo de 3 pasos.

Al final de esta guía, su tema o plugin estará:

  • Internacionalizado correctamente según los estándares de codificación de WordPress.
  • Traducible por PTC a más de 40 idiomas.
  • Distribuible a través de los paquetes de idiomas de WordPress.org.
  • Verificable en cada lanzamiento con la revisión visual de la traducción de PTC.

¿Qué es la internacionalización de WordPress?

La internacionalización (i18n) es el trabajo de preparar su código para que pueda ser traducido. La localización (l10n) es el siguiente paso. Produce las cadenas traducidas reales para idiomas específicos.

Para los temas y plugins de WordPress, la i18n implica tres cosas:

  • Envolver cada cadena orientada al usuario en funciones gettext para que WordPress pueda intercambiarlas en tiempo de ejecución.
  • Definir un dominio de texto que vincule sus traducciones a su proyecto.
  • Generar un archivo POT a partir del cual trabajen los traductores (o PTC).

Una vez realizado ese trabajo, tendrá todo lo necesario para producir archivos PO, MO, JSON y .l10n.php traducidos para cualquier idioma.

PTC traduce archivos POT a MO, JSON y .l10n.php para WordPress

Cinco extensiones de archivo aparecen en cualquier flujo de trabajo de traducción de WordPress. PTC traduce de .pot (su origen) a .po, .mo, .json y .l10n.php para cada idioma de destino. Cada formato tiene una función específica:

  • POT (Portable Object Template). El archivo de origen generado a partir de su código. Enumera cada cadena traducible sin traducciones adjuntas. Usted se lo entrega a PTC.
  • PO (Portable Object). Una copia del POT con traducciones añadidas para un idioma específico. Texto sin formato, legible por humanos. PTC devuelve un PO por cada idioma de destino.
  • MO (Machine Object). La versión binaria compilada de un PO. WordPress lee los archivos MO en tiempo de ejecución porque se cargan más rápido que el texto de los PO.
  • JSON. El equivalente en JavaScript del MO. WordPress no puede leer MO desde JavaScript, por lo que el pipeline de compilación produce archivos JSON para las cadenas del lado del navegador.
  • .l10n.php. Una alternativa más reciente al MO, introducida en WordPress 6.5. Se carga más rápido y utiliza menos memoria. WordPress lo selecciona automáticamente cuando existe uno junto al archivo MO.

Habilite .l10n.php para los proyectos nuevos. Es estrictamente mejor que el MO en las versiones de WordPress compatibles.

Por qué la traducción de la comunidad no es suficiente

WordPress.org ofrece traducción de la comunidad a través de GlotPress. En la práctica, cubre una pequeña fracción de lo que necesitan la mayoría de los plugins y temas. Un análisis de más de 60.000 plugins y temas de WordPress determinó que la traducción de la comunidad cubre menos del 5 % de las necesidades de traducción en 40 idiomas.

Dos problemas estructurales explican esta brecha:

  • Los voluntarios son escasos en la mayoría de los locales. Un puñado de plugins con bases masivas de usuarios atraen a los traductores. La mayoría no lo hace.
  • Las traducciones pueden tardar meses o años en aparecer, si es que lo hacen. Si desea que los usuarios vean su plugin o tema en su idioma desde el primer día, no puede depender de la comunidad.

Esta guía asume que usted desea una cobertura de traducción completa y coherente en un calendario de lanzamientos que usted controle. Eso es lo que ofrece PTC.

Cómo preparar su tema o plugin de WordPress para la traducción

Un dominio de texto que no coincida o una cadena sin envolver significa que ese texto nunca aparecerá en su resultado traducido. Los detalles importan.

Paso 1: Defina su dominio de texto y su ruta de dominio

Cada tema o plugin necesita un dominio de texto. El dominio de texto es un identificador único que le indica a WordPress qué archivos de traducción pertenecen a su proyecto. Debe coincidir exactamente con el slug de su plugin o tema.

Declárelo en el encabezado del archivo principal de su plugin:

<?php
/**
 * Plugin Name: My Plugin
 * Description: An example plugin.
 * Version: 1.0.0
 * Text Domain: my-plugin
 * Domain Path: /languages
 */

O en el style.css de su tema:

/*
Theme Name: My Theme
Text Domain: my-theme
Domain Path: /languages
*/

La ruta del dominio le indica a WordPress dónde se encuentran sus archivos de traducción en relación con la raíz del plugin o tema. /languages es el estándar.

Paso 2: Envuelva sus cadenas de PHP en funciones gettext

Cualquier cadena que desee traducir debe estar envuelta en una de las funciones gettext de WordPress. En tiempo de ejecución, estas funciones buscan la traducción correcta. Si no encuentran ninguna, recurren a la cadena original.

Cadenas básicas. Use __() cuando necesite devolver una cadena. Para la salida HTML, utilice las variantes escapadas. Los estándares de codificación de WordPress recomiendan echo esc_html__() en lugar de _e(). La forma escapada hace explícito el escape de salida y evita ataques XSS en el punto de salida:

// Return a translated string
$label = __( 'Settings', 'my-plugin' );

// Echo a translated string, escaped for HTML
echo esc_html__( 'Settings saved.', 'my-plugin' );

Cadenas con variables. No concatene variables en las cadenas. Los traductores solo ven fragmentos y no pueden reordenar las palabras para los idiomas con una sintaxis diferente. Use printf() o sprintf() con un marcador de posición. Añada un comentario para el traductor para que los traductores sepan qué representa %s:

printf(
    /* translators: %s: the user's display name */
    esc_html__( 'Welcome back, %s.', 'my-plugin' ),
    esc_html( $display_name )
);

Formas plurales. Los plurales en inglés son sencillos (one comment, two comments). En otros idiomas no lo son. Use _n() para procesar cada regla de plural que WordPress conoce:

printf(
    esc_html( _n( '%s comment', '%s comments', $count, 'my-plugin' ) ),
    number_format_i18n( $count )
);

Cadenas que necesitan contexto. Algunas palabras significan cosas diferentes dependiendo de dónde aparezcan. Use _x() para dar a los traductores el contexto que necesitan:

// "Export" as a noun (the file) vs. a verb (the action)
echo esc_html_x( 'Export', 'button label', 'my-plugin' );

Paso 3: Internacionalice sus cadenas de JavaScript

WordPress proporciona el paquete wp-i18n para que pueda usar en JavaScript las mismas funciones gettext que usa en PHP. Al registrar su script, declare wp-i18n como dependencia:

wp_register_script(
    'my-plugin-script',
    plugins_url( 'js/app.js', __FILE__ ),
    array( 'wp-i18n' ),
    '1.0.0',
    true
);

Luego, en su archivo JavaScript:

const { __, _n, sprintf } = wp.i18n;

const message = __( 'Settings saved.', 'my-plugin' );

Si usa un empaquetador como Webpack, instale @wordpress/babel-plugin-makepot. Este extrae las cadenas traducibles de su paquete como parte de su compilación.

Paso 4: Genere su archivo POT

Una vez que sus cadenas estén envueltas, genere un archivo POT. El POT es el archivo de origen a partir del cual PTC (o cualquier traductor) trabaja. Contiene todas las cadenas traducibles pero ninguna traducción.

wp i18n make-pot . languages/my-plugin.pot

WP-CLI analiza sus archivos PHP, JavaScript y block.json en busca de llamadas a gettext. Los compila en un único POT. Si su equipo usa Composer, añada este comando como un script de Composer. Eso mantiene el uso de WP-CLI de forma coherente en todo el equipo sin necesidad de una instalación global.

La suite completa de comandos wp i18n cubre el resto del pipeline:

Comando Qué hace
wp i18n make-pot Generar un archivo POT a partir del origen.
wp i18n update-po Sincronizar los archivos PO existentes cuando su POT cambia.
wp i18n make-mo Compilar los archivos PO en archivos MO binarios.
wp i18n make-json Extraer las cadenas de JS del PO en archivos JSON.
wp i18n make-php Generar archivos .l10n.php (WordPress 6.5+).

No necesita Poedit. Todo en este flujo de trabajo pasa por WP-CLI y PTC. WP-CLI procesa la generación del POT y la compilación de MO/JSON. PTC procesa la traducción y devuelve todos los formatos de archivo que WordPress necesita. Poedit es un editor de escritorio útil para la traducción manual, pero no forma parte de este flujo de trabajo.

Traducir archivos POT con PTC

PTC está creado pensando en los desarrolladores de WordPress. Comience con un archivo POT y reciba archivos de traducción listos para producción. La prueba de 30 días cubre hasta 20.000 palabras en dos idiomas.

Configure su primer proyecto de traducción

Suba su archivo POT. Elija qué formatos de salida necesita. PTC devuelve cualquier combinación de:

  • Archivos .po para cada idioma de destino.
  • Archivos .mo, compilados y listos para publicar.
  • Archivos .json para sus cadenas de JavaScript.
  • Archivos .l10n.php para una carga más rápida en WordPress 6.5+.

El asistente de configuración le pide que describa su tema o plugin. PTC usa la descripción para generar traducciones con el tono y contexto adecuados. Añada términos específicos de la marca al glosario en esta etapa. El glosario mantiene los nombres, las etiquetas de funciones y cualquier otra terminología de manera coherente en todos los idiomas.

PTC analiza la estructura de gettext al subir el archivo. Reconoce los marcadores de posición (%s, %1$s, %d), las formas plurales (entradas extraídas con _n() con su encabezado Plural-Forms) y los contextos (entradas _x() con msgctxt). Luego genera las categorías de plural correctas para cada idioma. El polaco obtiene one / few / many / other. El japonés obtiene solo other. El árabe obtiene seis formas.

Pase a la localización continua

Una vez que sus primeros archivos estén traducidos, actualice al pago al consumo. Conecte PTC a su repositorio de GitHub, GitLab o Bitbucket. A partir de ese momento, no tendrá que subir archivos manualmente.

Haga un commit de un .ptc-config.yml que indique su archivo de origen y a dónde pertenecen las traducciones:

# .ptc-config.yml
source_locale: en
files:
  - file: languages/my-plugin.pot
    output: languages/my-plugin-{{lang}}.po
    additional_translation_files:
      - type: mo
        path: languages/my-plugin-{{lang}}.mo

Luego, añada la acción PTC Translate a su flujo de trabajo. Lleva una versión fijada de la CLI de PTC en su interior, por lo que su compilación no descarga nada en tiempo de ejecución:

# .github/workflows/translate.yml
name: Regenerate POT for PTC
on:
  push:
    branches: [main]
    paths:
      - 'languages/my-plugin.pot'
  workflow_dispatch: {}

jobs:
  translate:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
      - name: Generate POT
        run: |
          wp i18n make-pot . languages/my-plugin.pot --domain=my-plugin
      - uses: OnTheGoSystems/ptc-action@v1
        with:
          api-token: ${{ secrets.PTC_API_TOKEN }}
          create-pr: true

Tiene dos formas de automatizar esto. Con la integración con Git, PTC vigila su repositorio y abre un merge request con las traducciones actualizadas siempre que el archivo de origen cambie. Para ejecutar la traducción dentro de su propio trabajo de CI en su lugar, use la CLI de PTC: esta sube el archivo modificado, espera a que termine la traducción y descarga los archivos traducidos. Encontrará plantillas de flujo de trabajo listas para usar para GitHub Actions, GitLab CI y Bitbucket Pipelines en la guía de configuración del pipeline de CI/CD.

Cualquiera de los dos flujos entrega un merge request o una descarga con los archivos .po, .mo, .json y .l10n.php actualizados. Consulte la referencia de la API de PTC para ver los webhooks completos y la API REST.

Hacer un commit de los archivos .mo en su repositorio depende de la política del equipo. En su lugar, muchos plugins los generan en el momento del lanzamiento. La integración de CI de PTC los produce en cada ejecución de traducción. Añádalos al control de versiones solo si desea tener los archivos traducidos en el historial de versiones.

Cargar traducciones en WordPress

Con los archivos traducidos en mano, colóquelos correctamente e indique a WordPress dónde encontrarlos. El nombre del archivo es lo primero. WordPress busca los archivos de traducción usando un patrón de nomenclatura específico. Un nombre de archivo que no coincida significa que el archivo no se cargará.

Nombrar los archivos correctamente

Los códigos de locale siguen el formato language_COUNTRY. de_DE es alemán (Alemania). fr_FR es francés (Francia). pt_BR es portugués (Brasil). zh_CN es chino (simplificado). El portal de traducción de WordPress enumera cada locale compatible.

El nombre de archivo esperado depende de dónde coloque el archivo:

Ubicación Patrón Ejemplo
Carpeta /languages/ del plugin {text-domain}-{locale}.mo my-plugin-de_DE.mo
Carpeta /languages/ del tema {locale}.mo de_DE.mo
Directorio global de idiomas de WordPress (/wp-content/languages/) {text-domain}-{locale}.mo my-plugin-de_DE.mo

Los temas usan una convención de nomenclatura más corta cuando los archivos se incluyen en el paquete del tema. En el directorio global de idiomas, tanto los plugins como los temas usan el patrón {text-domain}-{locale}.

Cargar traducciones para plugins (PHP)

Registre las traducciones en WordPress en el hook init. No use plugins_loaded. Este desencadena una advertencia de obsolescencia en las versiones actuales de WordPress:

add_action( 'init', function () {
    load_plugin_textdomain(
        'my-plugin',
        false,
        dirname( plugin_basename( __FILE__ ) ) . '/languages/'
    );
} );

Cargar traducciones para temas (PHP)

Use load_theme_textdomain() asociado al hook after_setup_theme:

add_action( 'after_setup_theme', function () {
    load_theme_textdomain( 'my-theme', get_template_directory() . '/languages' );
} );

Cargar traducciones de JavaScript

Después de registrar su script (Paso 3 anterior), llame a wp_set_script_translations(). A continuación, WordPress carga las traducciones en JSON para ese identificador del script:

add_action( 'init', function () {
    wp_set_script_translations(
        'my-plugin-script',
        'my-plugin',
        plugin_dir_path( __FILE__ ) . 'languages'
    );
} );

Verificar la carga

  1. Configure el idioma de su sitio de WordPress en un locale de destino. El ajuste se encuentra en Ajustes > Generales > Idioma del sitio.
  2. Vuelva a cargar el front end y las páginas de administración que renderiza su plugin o tema.
  3. Las cadenas envueltas en __() o esc_html__() deberían aparecer en el nuevo idioma.

Si falta algo, consulte ¿No se muestran las traducciones del plugin de WordPress? Solucione las traducciones faltantes para conocer las causas más comunes.

Idiomas de derecha a izquierda y diseños bidireccionales

El flujo de trabajo de traducción es el mismo para los idiomas de derecha a izquierda (RTL). El árabe, el hebreo, el persa y el urdu usan el mismo pipeline de POT/PO/MO.

El paso adicional es asegurarse de que su tema sea compatible con los estilos RTL. WordPress carga automáticamente un archivo rtl.css si existe uno en el directorio de su tema. Use la función is_rtl() para aplicar condicionalmente estilos o scripts específicos para RTL.

Localizar fechas, números y monedas

Una cadena traducida no es toda la historia. Las fechas, los números y las monedas también deben seguir el locale del usuario. Use las funciones de formato integradas de WordPress en lugar de las nativas de PHP:

  • date_i18n() da formato a las fechas según el locale activo.
  • number_format_i18n() da formato a los números con separadores de miles y decimales adaptados al locale.

Estas funciones no forman parte del flujo de trabajo de los archivos de traducción. Son importantes para lograr una experiencia completamente localizada.

Internacionalizar los bloques del editor de bloques (Gutenberg)

Los bloques añaden dos pasos adicionales al pipeline estándar:

  • Las traducciones de JavaScript necesitan un archivo .json por locale. Genérelo a partir del .po con wp i18n make-json.
  • El script del editor del bloque necesita wp_set_script_translations() en PHP. Esto le indica a WordPress que sirva el JSON al bloque.

La salida renderizada del bloque en el front end utiliza las mismas llamadas __() que el resto de su código PHP. No requiere trabajo adicional.

Traducir su README y la ficha de WordPress.org

Su readme.txt no es un archivo de recursos. WP-CLI no lo detectará al generar un POT. Para traducirlo, utilice la función Paste to Translate de PTC. Pegue el contenido, elija sus idiomas de destino y descargue el resultado. Los correos electrónicos dirigidos al cliente enviados desde el plugin y la descripción de la página del plugin en WordPress.org se traducen de la misma manera, todos en el mismo proyecto para que la terminología se mantenga coherente.

Si su plugin o tema aparece en el directorio de WordPress.org, la descripción traducida aparecerá en la pestaña Detalles del plugin en el idioma del usuario. Para que las traducciones se publiquen allí, siga el proceso de importación de WordPress.org.

Traducir el contenido de usuario del plugin con la API de PTC

Los plugins que almacenan datos generados por los usuarios (plugins de foros, de reseñas, de comentarios) pueden traducir ese contenido a medida que llega. La API REST de PTC traduce las publicaciones, los comentarios y las reseñas de los usuarios bajo demanda con autenticación Bearer, utilizando el mismo glosario y voz de marca que sus archivos .po.

Revisión visual de la traducción de su tema o plugin renderizado: publique sin control de calidad manual por idioma

Un archivo .po traducido es necesario, pero no es suficiente. El tema o plugin traducido aún necesita verificación:

  • Una etiqueta traducida puede desbordar un botón de la página de configuración en alemán.
  • “Submit” puede traducirse como un sustantivo en francés cuando la acción de administración necesitaba un verbo.
  • Una cadena en inglés incrustada en el código fuera de __() se renderizará sin traducir independientemente de cuántos idiomas publique.

La revisión visual de la traducción de PTC reemplaza el control de calidad manual. Los temas y plugins de WordPress se renderizan en el navegador (tanto en wp-admin como en el front end). La variante adecuada es la extensión de navegador.

Instálela una vez. Grabe un recorrido de su tema o plugin en un sitio de prueba. Cubra las páginas de configuración, las acciones de administración y la salida del front end. PTC vuelve a ejecutar la grabación en cada idioma de destino después de cada actualización de traducción. Captura cada pantalla y notifica dos tipos de correcciones:

  • Correcciones en los archivos .po cuando PTC los controla. PTC vuelve a traducir una acepción incorrecta, elige un sinónimo más corto que encaje en un botón o regenera una forma plural.
  • Prompts de Cursor o Claude Code cuando el problema reside en su código PHP o JavaScript. Los ejemplos incluyen un wrapper __() faltante, una cadena en inglés incrustada en el código o una oración construida por concatenación que debería usar sprintf( __( ... ) ).

Usted publica un plugin multilingüe y verificado en cada lanzamiento. El trabajo residual de control de calidad manual desaparece.

Precios: prueba de 30 días, luego pago al consumo

La prueba cubre 20.000 palabras en 2 idiomas sin tarjeta de crédito. Cuando termina la prueba, PTC ofrece el pago al consumo. Sin suscripciones. Sin compromiso mínimo. Las primeras 500 palabras de cada mes son gratuitas. Solo paga por el resto. La página de precios tiene una calculadora de costes. Regístrese con un correo electrónico de empresa para obtener una prueba ampliada para empresas.

¿Listo para publicar un plugin o tema verificado?

PTC genera las traducciones y revisa el plugin renderizado. Usted confirma el resultado y lo publica. El ciclo completo se ejecuta sin control de calidad manual:

  1. Genere su archivo .pot con wp i18n make-pot.
  2. Súbalo a PTC y reciba los archivos .po, .mo, .l10n.php y .json en minutos.
  3. Instale la extensión de navegador para verificar el plugin en ejecución en cada idioma de destino.

Comience su prueba de 30 días: 20.000 palabras por nuestra cuenta, sin necesidad de tarjeta de crédito.

Relacionado: