Internacionalização do WordPress: Como traduzir temas e plugins
Deixe seu tema ou plugin do WordPress pronto para tradução. Este guia aborda 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 revisa visualmente o tema ou plugin renderizado em cada idioma.
Este guia é para desenvolvedores que escrevem o código. Se você já tem um arquivo POT ou PO e apenas precisa traduzi-lo, acesse a página de arquivos PO para conhecer 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 codificação do WordPress.
- Traduzível pela PTC para 40+ idiomas.
- Distribuível via pacotes de idiomas 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 substituí-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.
Assim que 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 para 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 do .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 traduzível sem nenhuma tradução anexada. Você entrega isso para a 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 no 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 existir um junto ao arquivo MO.
Habilite o .l10n.php para novos projetos. Ele é estritamente melhor do 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.
- 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
Todo tema ou plugin precisa de um text domain. O text domain é um identificador exclusivo que informa 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 codificação do WordPress recomendam echo esc_html__() em vez de _e(). A forma escapada torna o escape de saída explícito e evita 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 conseguem reordenar as 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 têm significados 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 em JavaScript que você usa em 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
);
Então, no seu arquivo JavaScript:
const { __, _n, sprintf } = wp.i18n;
const message = __( 'Settings saved.', 'my-plugin' );
Se você usa um bundler como o Webpack, instale o @wordpress/babel-plugin-makepot. Ele extrai as strings traduzíveis do seu bundle como parte do seu processo de build.
Passo 4: Gere seu arquivo POT
Depois que 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 todas as strings traduzíveis, mas nenhuma tradução.
wp i18n make-pot . languages/my-plugin.pot
O WP-CLI escaneia seus arquivos PHP, JavaScript e block.json em busca de chamadas gettext. Ele os compila em um único POT. Se o seu time usa o Composer, adicione este comando como um script do Composer. Isso mantém o uso do WP-CLI consistente em todo o time sem uma instalação global.
O conjunto completo de comandos wp i18n cobre o resto do pipeline:
| Comando | O que ele faz |
|---|---|
wp i18n make-pot |
Gera um arquivo POT a partir do código-fonte. |
wp i18n update-po |
Sincroniza os arquivos PO existentes quando seu POT muda. |
wp i18n make-mo |
Compila os arquivos PO em arquivos MO binários. |
wp i18n make-json |
Extrai as 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 é executado através do WP-CLI e da PTC. O WP-CLI lida com a geração do POT e com 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 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 de quais formatos de saída você precisa. A PTC retorna qualquer combinação de:
- Arquivos
.popara cada idioma de destino. - Arquivos
.mo, compilados e prontos para lançamento. - Arquivos
.jsonpara suas strings JavaScript. - Arquivos
.l10n.phppara 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 do gettext no momento do 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
Depois que seus primeiros arquivos estiverem traduzidos, faça o upgrade para o Pay-As-You-Go. Conecte a PTC ao seu repositório no GitHub, GitLab ou Bitbucket. A partir desse ponto, você não faz o upload de arquivos manualmente.
Faça o commit de um .ptc-config.yml nomeando seu arquivo de origem e indicando onde as traduções devem ficar:
# .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
Em seguida, adicione a ação PTC Translate ao seu fluxo de trabalho. Ela carrega uma versão fixada da CLI da PTC internamente, para que a sua compilação não baixe nada em tempo de execução:
# .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
Você tem duas maneiras de automatizar isso. Com a integração com Git, a PTC monitora o seu repositório e abre um merge request com as traduções atualizadas sempre que o arquivo de origem muda. Para rodar a tradução dentro da sua própria tarefa de CI, use a CLI da PTC - ela envia o arquivo alterado, espera a tradução terminar e baixa os arquivos traduzidos. Modelos prontos de fluxo de trabalho para 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 um download com os arquivos .po, .mo, .json e .l10n.php atualizados. Consulte a referência da API da PTC para ver o webhook completo e a API REST.
Fazer ou não o commit dos arquivos .mo no seu repositório depende da política do time. 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 commit deles apenas se você quiser os 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 por arquivos de tradução usando um padrão de nomenclatura específico. Um nome de arquivo que não corresponda 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 empacotados dentro do tema. No diretório global de idiomas, tanto os plugins quanto os 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 dispara 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 em JavaScript
Após registrar o seu script (Passo 3 acima), chame wp_set_script_translations(). O WordPress então carrega as traduções em 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
- Defina o idioma do seu site WordPress para um locale de destino. A configuração está em Configurações > Geral > Idioma do site.
- Recarregue o front-end e as páginas administrativas que o seu plugin ou tema renderiza.
- As strings envolvidas em
__()ouesc_html__()devem aparecer no novo idioma.
Se algo estiver faltando, consulte As traduções do plugin do WordPress não estão aparecendo? Corrija traduções ausentes para ver 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 o seu tema suporte estilos RTL. O WordPress carrega automaticamente um arquivo rtl.css se ele existir no diretório do seu tema. Use a função is_rtl() para aplicar condicionalmente estilos ou scripts específicos para RTL.
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 de arquivos 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 em JavaScript precisam de um arquivo
.jsonpor locale. Gere-o a partir do.pocom owp 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 para o bloco.
A saída renderizada do 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 no WordPress.org
O 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 baixe o 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 forma, 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, comentários e avaliações de usuários sob demanda com autenticação por token Bearer, usando o mesmo glossário e voz da marca que os seus arquivos .po.
Revisão visual de tradução do seu tema ou plugin renderizado - lance 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 em inglês hardcoded fora do
__()será renderizada sem tradução, independentemente de quantos idiomas você lançar.
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. Faça um percurso gravado do seu tema ou plugin em um site de teste. Cubra as páginas de configurações, ações administrativas e a saída do front-end. A PTC repete a gravação em todos os idiomas 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
.poquando a PTC os controla. A PTC retraduz uma acepção incorreta, escolhe um sinônimo mais curto que caiba em um botão ou gera novamente 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 em inglês hardcoded ou uma frase construída por concatenação que deveria usar osprintf( __( ... ) ).
Você lança um plugin multilíngue e verificado a cada 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 restante. A página de preços possui uma calculadora de custos. Cadastre-se com um e-mail corporativo para um teste corporativo estendido.
Pronto para lançar 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:
- Gere seu arquivo
.potcom owp i18n make-pot. - Faça o upload dele para a PTC e receba os arquivos
.po,.mo,.l10n.phpe.jsonde volta em minutos. - Instale a extensão do navegador para verificar o plugin em execução em todos os idiomas de destino.
Comece seu teste de 30 dias - 20.000 palavras por nossa conta, sem necessidade de cartão de crédito.
Relacionados:
- Traduza arquivos PO online com IA - a página canônica de tradução de PO/POT.
- GlotPress vs PTC para tradução de plugins/temas do WordPress - quando escolher as traduções da comunidade vs a PTC.
- As traduções do plugin do WordPress não estão aparecendo? Corrija traduções ausentes - guia de solução de problemas.
- Como importar traduções de temas e plugins para o WordPress.org - processo CLPTE e uma alternativa mais rápida.
- Referência da API da PTC - endpoints REST para integração de CI.