PTC

Internacionalização do WordPress: como traduzir temas e plugins

Deixe seu tema ou plugin do WordPress pronto para tradução. Este guia abrange text domains, funções gettext, geração de POT e o mecanismo de carregamento que coloca as traduções diante dos usuários. A PTC (Private Translation Cloud) então traduz os arquivos de recursos e faz a revisão visual de tradução do tema ou plugin renderizado em cada idioma.

Este guia é para desenvolvedores que estão escrevendo o código. Se você já tem um arquivo POT ou PO e só precisa traduzi-lo, acesse a página de arquivos PO para ver o fluxo de trabalho de 3 etapas.

Ao final deste guia, seu tema ou plugin estará:

  • Internacionalizado corretamente de acordo com os padrões de código do WordPress.
  • Pronto para tradução pela PTC para 40+ idiomas.
  • Pronto para distribuição via pacotes de idioma do WordPress.org.
  • Verificável a cada lançamento com a revisão visual de tradução da PTC.

O que é a internacionalização do WordPress?

A internacionalização (i18n) é o trabalho de preparar seu código para que ele possa ser traduzido. A localização (l10n) é a próxima etapa. Ela produz as strings traduzidas reais para idiomas específicos.

Para temas e plugins do WordPress, i18n significa três coisas:

  • Envolver cada string voltada para o usuário em funções gettext para que o WordPress possa trocá-las em tempo de execução.
  • Definir um text domain que vincula suas traduções ao seu projeto.
  • Gerar um arquivo POT a partir do qual os tradutores (ou a PTC) trabalham.

Quando esse trabalho estiver concluído, você terá tudo o que precisa para produzir arquivos PO, MO, JSON e .l10n.php traduzidos para qualquer idioma.

A PTC traduz arquivos POT em MO, JSON e .l10n.php para o WordPress

Cinco extensões de arquivo aparecem em qualquer fluxo de trabalho de tradução do WordPress. A PTC traduz de .pot (sua fonte) para .po, .mo, .json e .l10n.php para cada idioma de destino. Cada formato tem um papel específico:

  • POT (Portable Object Template). O arquivo de origem gerado a partir do seu código. Ele lista cada string de tradução sem traduções anexadas. Você entrega isso à PTC.
  • PO (Portable Object). Uma cópia do POT com traduções adicionadas para um idioma específico. Texto simples, legível por humanos. A PTC retorna um PO por idioma de destino.
  • MO (Machine Object). A versão binária compilada de um PO. O WordPress lê arquivos MO em tempo de execução porque eles carregam mais rápido do que o texto do PO.
  • JSON. O equivalente em JavaScript do MO. O WordPress não consegue ler MO a partir do JavaScript, então o pipeline de compilação produz arquivos JSON para strings do lado do navegador.
  • .l10n.php. Uma alternativa mais recente ao MO, introduzida no WordPress 6.5. Ele carrega mais rápido e usa menos memória. O WordPress o escolhe automaticamente quando um existe junto com o arquivo MO.

Habilite .l10n.php para novos projetos. Ele é estritamente melhor que o MO nas versões suportadas do WordPress.

Por que a tradução da comunidade não é suficiente

O WordPress.org oferece tradução da comunidade através do GlotPress. Na prática, isso cobre uma pequena fração do que a maioria dos plugins e temas precisa. Uma análise de mais de 60.000 plugins e temas do WordPress descobriu que a tradução da comunidade cobre menos de 5% das necessidades de tradução em 40 idiomas.

Dois problemas estruturais explicam a lacuna:

  • Voluntários são escassos na maioria dos locales. Um punhado de plugins com bases de usuários massivas atrai tradutores. A maioria não.
  • As traduções podem levar meses ou anos para aparecer, se é que aparecem. Se você quer que os usuários vejam seu plugin ou tema no idioma deles desde o primeiro dia, você não pode depender da comunidade.

Este guia pressupõe que você deseja uma cobertura de tradução completa e consistente em um cronograma de lançamento que você controla. É isso que a PTC oferece.

Preparando seu tema ou plugin do WordPress para tradução

Um text domain incompatível ou uma string não envolvida significa que esse texto nunca aparecerá na sua saída traduzida. Os detalhes importam.

Passo 1: Defina seu text domain e caminho do domínio

Cada tema ou plugin precisa de um text domain. O text domain é um identificador exclusivo que diz ao WordPress quais arquivos de tradução pertencem ao seu projeto. Ele deve corresponder exatamente ao slug do seu plugin ou tema.

Declare-o no cabeçalho do arquivo principal do seu plugin:

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

Ou no style.css do seu tema:

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

O caminho do domínio diz ao WordPress onde seus arquivos de tradução ficam em relação à raiz do plugin ou tema. /languages é o padrão.

Passo 2: Envolva suas strings PHP em funções gettext

Qualquer string que você queira que seja traduzível precisa ser envolvida em uma das funções gettext do WordPress. Em tempo de execução, essas funções buscam a tradução correta. Se nenhuma for encontrada, elas fazem o fallback para a string original.

Strings básicas. Use __() quando precisar retornar uma string. Para saída HTML, use as variantes escapadas. Os padrões de código do WordPress recomendam echo esc_html__() em vez de _e(). A forma escapada torna o escape de saída explícito e previne XSS no ponto de saída:

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

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

Strings com variáveis. Não concatene variáveis em strings. Os tradutores veem apenas fragmentos e não podem reordenar palavras para idiomas com sintaxe diferente. Use printf() ou sprintf() com um placeholder. Adicione um comentário para o tradutor para que os tradutores saibam o que %s representa:

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

Formas plurais. Os plurais em inglês são simples (one comment, two comments). Outros idiomas não são. Use _n() para lidar com todas as regras de plural que o WordPress conhece:

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

Strings que precisam de contexto. Algumas palavras significam coisas diferentes dependendo de onde aparecem. Use _x() para dar aos tradutores o contexto de que precisam:

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

Passo 3: Internacionalize suas strings JavaScript

O WordPress fornece o pacote wp-i18n para que você possa usar as mesmas funções gettext no JavaScript que você usa no PHP. Ao registrar seu script, declare wp-i18n como uma dependência:

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

Em seguida, no seu arquivo JavaScript:

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

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

Se você usa um bundler como o Webpack, instale @wordpress/babel-plugin-makepot. Ele extrai strings traduzíveis do seu bundle como parte da sua compilação.

Passo 4: Gere seu arquivo POT

Quando suas strings estiverem envolvidas, gere um arquivo POT. O POT é o arquivo de origem a partir do qual a PTC (ou qualquer tradutor) trabalha. Ele contém cada string traduzível, mas nenhuma tradução.

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

O WP-CLI examina seus arquivos PHP, JavaScript e block.json em busca de chamadas gettext. Ele as compila em um único POT. Se sua equipe usa o Composer, adicione este comando como um script do Composer. Isso mantém o uso do WP-CLI consistente em toda a equipe sem uma instalação global.

O conjunto completo de comandos wp i18n cobre o restante do pipeline:

Comando O que ele faz
wp i18n make-pot Gera um arquivo POT a partir da fonte.
wp i18n update-po Sincroniza os arquivos PO existentes quando seu POT muda.
wp i18n make-mo Compila arquivos PO em arquivos MO binários.
wp i18n make-json Extrai strings JS do PO para arquivos JSON.
wp i18n make-php Gera arquivos .l10n.php (WordPress 6.5+).

Você não precisa do Poedit. Tudo neste fluxo de trabalho passa pelo WP-CLI e pela PTC. O WP-CLI lida com a geração do POT e a compilação de MO/JSON. A PTC lida com a tradução e retorna todos os formatos de arquivo de que o WordPress precisa. O Poedit é um editor de desktop útil para tradução manual, mas não faz parte deste fluxo de trabalho.

Traduzindo arquivos POT com a PTC

A PTC foi criada pensando nos desenvolvedores do WordPress. Comece com um arquivo POT e receba de volta arquivos de tradução prontos para produção. O teste de 30 dias cobre até 20.000 palavras em dois idiomas.

Configure seu primeiro projeto de tradução

Faça o upload do seu arquivo POT. Escolha quais formatos de saída você precisa. A PTC retorna qualquer combinação de:

  • Arquivos .po para cada idioma de destino.
  • Arquivos .mo, compilados e prontos para publicar.
  • Arquivos .json para suas strings JavaScript.
  • Arquivos .l10n.php para um carregamento mais rápido no WordPress 6.5+.

O assistente de configuração pede que você descreva seu tema ou plugin. A PTC usa a descrição para gerar traduções com o tom e o contexto certos. Adicione termos específicos da marca ao glossário nesta etapa. O glossário mantém nomes, rótulos de recursos e qualquer outra terminologia consistentes em todos os idiomas.

A PTC analisa a estrutura gettext no upload. Ela reconhece placeholders (%s, %1$s, %d), formas plurais (entradas extraídas com _n() com seu cabeçalho Plural-Forms) e contextos (entradas _x() com msgctxt). Em seguida, ela gera as categorias de plural corretas por idioma. O polonês recebe one / few / many / other. O japonês recebe apenas other. O árabe recebe seis formas.

Mude para a localização contínua

Quando seus primeiros arquivos estiverem traduzidos, faça o upgrade para o Pay-As-You-Go. Conecte a PTC ao seu repositório do GitHub, GitLab ou Bitbucket. A partir desse ponto, você não faz o upload de arquivos manualmente:

# .github/workflows/translate.yml
name: Regenerate POT for PTC
on:
  push:
    branches: [main]
    paths:
      - 'languages/my-plugin.pot'
jobs:
  translate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Generate POT
        run: |
          wp i18n make-pot . languages/my-plugin.pot --domain=my-plugin
      - name: Translate with PTC
        run: |
          cat > .ptc-config.yml <<'EOF'
          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
          EOF
          curl -fsSL https://raw.githubusercontent.com/OnTheGoSystems/ptc-cli/main/ptc-cli.sh -o ptc-cli.sh
          chmod +x ptc-cli.sh
          ./ptc-cli.sh --config-file .ptc-config.yml --api-token="${{ secrets.PTC_API_TOKEN }}"

Você tem duas maneiras de automatizar isso. Com a integração com Git, a PTC monitora seu repositório e abre um merge request com as traduções atualizadas sempre que o arquivo de origem mudar. Para executar a tradução dentro da sua própria tarefa de CI, use a CLI da PTC - ela faz o upload do arquivo alterado, espera a tradução terminar e faz o download dos arquivos traduzidos. Modelos de fluxo de trabalho prontos para o GitHub Actions, GitLab CI e Bitbucket Pipelines estão no guia de configuração do pipeline de CI/CD.

Qualquer um dos fluxos entrega um merge request ou download com os arquivos .po, .mo, .json e .l10n.php atualizados. Consulte a referência da API da PTC para ver a API REST e os webhooks completos.

Fazer o commit dos arquivos .mo no seu repositório depende da política da equipe. Em vez disso, muitos plugins os geram no momento do lançamento. A integração de CI da PTC os produz a cada execução de tradução. Faça o check-in deles apenas se você quiser arquivos traduzidos no histórico de versões.

Carregando traduções no WordPress

Com os arquivos traduzidos em mãos, coloque-os corretamente e diga ao WordPress onde encontrá-los. O nome do arquivo vem primeiro. O WordPress procura arquivos de tradução usando um padrão de nomenclatura específico. Um nome de arquivo que não corresponde significa que o arquivo não será carregado.

Acertando os nomes dos seus arquivos

Os códigos de locale seguem o formato language_COUNTRY. de_DE é alemão (Alemanha). fr_FR é francês (França). pt_BR é português (Brasil). zh_CN é chinês simplificado. O portal de tradução do WordPress lista todos os locales suportados.

O nome de arquivo esperado depende de onde você coloca o arquivo:

Localização Padrão Exemplo
Pasta /languages/ do plugin {text-domain}-{locale}.mo my-plugin-de_DE.mo
Pasta /languages/ do tema {locale}.mo de_DE.mo
Diretório global de idiomas do WordPress (/wp-content/languages/) {text-domain}-{locale}.mo my-plugin-de_DE.mo

Os temas usam uma convenção de nomenclatura mais curta quando os arquivos são agrupados dentro do tema. No diretório global de idiomas, tanto plugins quanto temas usam o padrão {text-domain}-{locale}.

Carregando traduções para plugins (PHP)

Registre as traduções no WordPress no hook init. Não use plugins_loaded. Ele aciona um aviso de descontinuação nas versões atuais do WordPress:

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

Carregando traduções para temas (PHP)

Use load_theme_textdomain() no hook after_setup_theme:

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

Carregando traduções JavaScript

Após registrar seu script (Passo 3 acima), chame wp_set_script_translations(). O WordPress então carrega as traduções JSON para esse handle de script:

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

Verifique o carregamento

  1. Defina o idioma do seu site WordPress para um locale de destino. A configuração está em Configurações > Geral > Idioma do site.
  2. Recarregue o front-end e as páginas administrativas que seu plugin ou tema renderiza.
  3. As strings envolvidas em __() ou esc_html__() devem aparecer no novo idioma.

Se algo estiver faltando, consulte Traduções de plugin do WordPress não aparecem? Corrija traduções ausentes para as causas mais comuns.

Idiomas da direita para a esquerda e layouts bidirecionais

O fluxo de trabalho de tradução é o mesmo para idiomas da direita para a esquerda (RTL). Árabe, hebraico, persa e urdu usam o mesmo pipeline POT/PO/MO.

O passo extra é garantir que seu tema suporte estilos RTL. O WordPress carrega automaticamente um arquivo rtl.css se houver um no diretório do seu tema. Use a função is_rtl() para aplicar estilos ou scripts específicos de RTL condicionalmente.

Localizando datas, números e moedas

Uma string traduzida não é toda a história. Datas, números e moedas também devem seguir o locale do usuário. Use as funções de formatação integradas do WordPress em vez das nativas do PHP:

  • date_i18n() formata datas de acordo com o locale ativo.
  • number_format_i18n() formata números com separadores decimais e de milhares sensíveis ao locale.

Essas funções não fazem parte do fluxo de trabalho do arquivo de tradução. Elas são importantes para uma experiência totalmente localizada.

Internacionalizando blocos do Editor de blocos (Gutenberg)

Os blocos adicionam dois passos extras ao pipeline padrão:

  • As traduções JavaScript precisam de um arquivo .json por locale. Gere-o a partir do .po com wp i18n make-json.
  • O script do editor do bloco precisa de wp_set_script_translations() no PHP. Isso diz ao WordPress para servir o JSON ao bloco.

A saída renderizada pelo bloco no front-end usa as mesmas chamadas __() que o seu outro PHP. Não há trabalho extra aí.

Traduzindo seu README e a ficha do WordPress.org

Seu readme.txt não é um arquivo de recursos. O WP-CLI não o incluirá ao gerar um POT. Para traduzi-lo, use o recurso Paste to Translate da PTC. Cole o conteúdo, escolha seus idiomas de destino e faça o download do resultado. Os e-mails voltados para o cliente enviados pelo plugin e a descrição da página do plugin no WordPress.org são traduzidos da mesma maneira, todos no mesmo projeto para que a terminologia permaneça consistente.

Se o seu plugin ou tema estiver listado no WordPress.org, a descrição traduzida aparecerá na aba Detalhes do plugin no idioma do usuário. Para que as traduções fiquem ativas lá, siga o processo de importação do WordPress.org.

Traduza o conteúdo do usuário do plugin com a API da PTC

Plugins que armazenam dados gerados pelo usuário (plugins de fórum, plugins de avaliação, plugins de comentários) podem traduzir esse conteúdo à medida que ele chega. A API REST da PTC traduz postagens de usuários, comentários e avaliações sob demanda com autenticação por token Bearer, usando o mesmo glossário e voz da marca que seus arquivos .po.

Revisão visual de tradução do seu tema ou plugin renderizado - publique sem QA manual por idioma

Um arquivo .po traduzido é necessário, mas não é suficiente. O tema ou plugin traduzido ainda precisa de verificação:

  • Um rótulo traduzido pode causar um estouro em um botão da página de configurações em alemão.
  • “Submit” pode ser traduzido como um substantivo em francês quando a ação administrativa precisava de um verbo.
  • Uma string hardcoded em inglês fora de __() será renderizada sem tradução, independentemente de quantos idiomas você publicar.

A revisão visual de tradução da PTC substitui o passe de QA manual. Os temas e plugins do WordPress são renderizados no navegador (tanto o wp-admin quanto o front-end). A variante certa é a extensão do navegador.

Instale-a uma vez. Grave um percurso gravado do seu tema ou plugin em um site de teste. Cubra páginas de configurações, ações administrativas e saída do front-end. A PTC reproduz a gravação em cada idioma de destino após cada atualização de tradução. Ela captura todas as telas e relata dois tipos de correções:

  • Correções nos arquivos .po quando a PTC os controla. A PTC retraduz uma acepção incorreta, escolhe um sinônimo mais curto que caiba em um botão ou regera uma forma plural.
  • Prompts do Cursor ou do Claude Code quando o problema está no seu código PHP ou JavaScript. Exemplos incluem um wrapper __() ausente, uma string hardcoded em inglês ou uma frase construída por concatenação que deveria usar sprintf( __( ... ) ).

Você publica um plugin multilíngue e verificado por lançamento. O trabalho residual de QA manual desaparece.

Preços: teste de 30 dias, depois Pay-As-You-Go

O teste cobre 20.000 palavras em 2 idiomas sem cartão de crédito. Quando o teste termina, a PTC oferece o Pay-As-You-Go. Sem assinatura. Sem compromisso mínimo. As primeiras 500 palavras de cada mês são gratuitas. Você só paga pelo resto. A página de preços tem uma calculadora de custos. Inscreva-se com um e-mail corporativo para um teste empresarial estendido.

Pronto para publicar um plugin ou tema verificado?

A PTC gera as traduções e revisa o plugin renderizado. Você confirma o resultado e faz o lançamento. O ciclo completo é executado sem QA manual:

  1. Gere seu arquivo .pot com wp i18n make-pot.
  2. Faça o upload dele para a PTC e receba de volta arquivos .po, .mo, .l10n.php e .json em minutos.
  3. Instale a extensão do navegador para verificar o plugin em execução em cada idioma de destino.

Comece seu teste de 30 dias - 20.000 palavras por nossa conta, sem necessidade de cartão de crédito.

Relacionados: