As traduções do plugin do WordPress não estão aparecendo? Corrija as traduções ausentes
Traduções ausentes após uma execução da PTC? Quatro verificações encontram quase todas as causas. Verifique se a string chegou à PTC, se o nome do arquivo .mo corresponde ao que o WordPress espera e se o text domain é consistente em todo o seu código. Este guia percorre cada verificação na ordem em que devem ser executadas.
A mesma ordem de diagnóstico funciona quer você tenha traduzido com a PTC (Private Translation Cloud), o GlotPress ou qualquer outra ferramenta baseada em gettext. Os modos de falha são inerentes ao pipeline de i18n do WordPress, e não a um tradutor específico.
Confirme se a string chegou à PTC
A primeira pergunta é se a string está no seu projeto da PTC. Se uma string não foi extraída para o seu arquivo .pot, a PTC nunca a viu. O arquivo .po não tem tradução para ela. O plugin em execução mostra o fallback do idioma de origem.
Como verificar:
- Abra a string afetada no plugin em execução e copie seu texto exato.
- Vá para o seu painel da PTC, abra a aba Translations e pesquise a string.
- Se ela não estiver lá, a PTC nunca a recebeu.
A seguir, estão três causas comuns.
Causa 1: a string está ausente do seu arquivo POT
O wp i18n make-pot extrai apenas strings dentro das funções i18n reconhecidas. Isso significa __(), _e(), _n(), _x() e as variantes escapadas, com o text domain correto. As strings dentro do domínio errado são ignoradas. As strings hardcoded fora de uma função i18n são ignoradas.
Execute a extração novamente e verifique se a string agora está no .pot:
wp i18n make-pot . languages/my-plugin.pot --domain=my-plugin
grep "Save Changes" languages/my-plugin.pot
Se grep retornar a string com um msgid, a extração funciona. Faça o upload do novo .pot para a PTC e traduza novamente. Se grep não retornar nada, a string é hardcoded e não está envolvida em __(). Esse é o seu bug. Envolva a string e extraia novamente.
Causa 2: o texto não está envolvido em uma função gettext
Toda string traduzível no seu código precisa de um wrapper. Use __(), esc_html__(), _e(), _n() ou _x() com o text domain correto:
__( 'Hello, world!', 'your-plugin' );
Causa 3: as strings de JavaScript não foram marcadas como traduzíveis
Se o seu plugin inclui texto traduzível em JavaScript:
- No painel da PTC, vá para Configurações > Arquivos Monitorados.
- Edite o arquivo de recursos relevante e ative “Is this a WordPress project with localizable JavaScript?”
Isso diz à PTC para escanear os arquivos JavaScript em busca de strings traduzíveis. A PTC gera as traduções novamente e abre um novo merge request com os arquivos atualizados.
Em seguida, certifique-se de que o WordPress sabe onde carregar os arquivos de tradução .json que a PTC produziu. Chame wp_set_script_translations() com o caminho correto:
// 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'
);
Isso diz ao WordPress para carregar os arquivos .json da pasta do seu plugin ou tema.
Confirme se o WordPress está carregando o seu arquivo .mo
Se a string está na PTC e o arquivo .mo existe no diretório languages/ do seu plugin, mas o plugin renderizado ainda mostra inglês, o WordPress está falhando ao carregar o .mo.
Diagnóstico 1: o locale do site está configurado corretamente? Vá para Configurações > Geral > Idioma do site no wp-admin e confirme se corresponde ao seu idioma de destino. Por exemplo, defina como “Español” para testar o espanhol. Se o site estiver em inglês, o seu .mo em espanhol nunca será carregado. Isso não é um bug.
Diagnóstico 2: load_plugin_textdomain() está realmente sendo executado? Adicione uma linha de depuração temporária:
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 ) );
} );
Recarregue uma página e verifique o seu log de erros do PHP. loaded: true significa que o WordPress encontrou e carregou um arquivo .mo para o locale atual. loaded: false significa que não. A causa geralmente é uma incompatibilidade de nome de arquivo (veja a próxima seção) ou um caminho de diretório incorreto.
Diagnóstico 3: o tempo do hook está correto? load_plugin_textdomain() deve ser executado no hook init. Esse é o hook canônico para que as traduções se apliquem às strings exibidas durante o processamento normal de requisições.
Diagnóstico 4: as traduções da comunidade estão substituindo os seus arquivos incluídos? Por padrão, o WordPress prioriza os arquivos de tradução armazenados em /wp-content/languages/. Se o seu plugin ou tema tiver traduções da comunidade no WordPress.org, esses arquivos podem substituir os arquivos .mo incluídos no seu projeto. Para evitar isso, use o filtro load_textdomain_mofile para forçar o carregamento do caminho do seu arquivo incluído antes que o WordPress verifique o diretório global. Projetos com múltiplos text domains (um plugin que incorpora outro plugin) precisam que cada domínio seja carregado separadamente. Cada domínio precisa da sua própria chamada load_plugin_textdomain() ou load_theme_textdomain().
Certifique-se de que o nome do arquivo MO corresponde ao padrão de busca do WordPress
A busca de arquivos .mo do WordPress segue uma convenção de nomenclatura rigorosa. Mesmo com um caractere incorreto, o WordPress fará o fallback silenciosamente para o inglês.
A convenção depende de onde você coloca o arquivo:
| Localização | Padrão | Exemplo |
|---|---|---|
/languages/ do plugin |
{text-domain}-{locale}.mo |
my-plugin-de_DE.mo |
/languages/ do tema |
{locale}.mo |
de_DE.mo |
Diretório global (/wp-content/languages/...) |
{text-domain}-{locale}.mo |
my-theme-de_DE.mo |
Alguns exemplos práticos:
my-plugin-es_ES.mopara espanhol (Espanha)my-plugin-fr_FR.mopara francês (França)my-plugin-pt_BR.mopara português (Brasil)my-plugin-zh_CN.mopara chinês simplificadomy-plugin-ja.mopara japonês (alguns locales não têm sufixo de região)
Erros comuns:
- Prefixo de text domain incorreto. Se o cabeçalho
Text Domaindo seu plugin formy-plugin, mas o.mofor nomeado comomyplugin-es_ES.mo(sem hífen), o WordPress não o encontrará. O prefixo deve corresponder exatamente ao valor deText Domain. - Código de locale incorreto.
es.moem vez dees_ES.mo. O WordPress usa códigos de locale regionais.es_ES,es_MXees_ARsão arquivos diferentes. Um código de idioma simples só funciona quando não existe um arquivo regional. - Hífen vs. sublinhado. Os códigos de locale usam sublinhado (
es_ES), nunca hífen (es-ES). Isso confunde os desenvolvedores que copiam códigos de locale de cabeçalhosAccept-Languagedo navegador ou fontes BCP 47, onde o hífen é o padrão. - Diretório incorreto. O cabeçalho
Domain Pathdeve apontar para o diretório que contém os seus arquivos.mo. SeDomain Pathfor/languagese os seus arquivos.moestiverem em/lang/, o WordPress não os encontrará.
Verifique listando os arquivos que a PTC produziu em comparação com o locale que o seu site está usando:
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
Se os nomes parecerem corretos, mas as traduções ainda não carregarem, execute o diagnóstico de load_plugin_textdomain() acima para confirmar se o WordPress está encontrando o diretório.
Verifique se o seu text domain é consistente em todo o seu código
Este é o assassino silencioso. Cada chamada __(), _e(), _n(), _x() no seu código passa um text domain como o seu último argumento. Se ao menos uma chamada passar o domínio errado, essa única string não será traduzida. Todas as outras strings no plugin funcionarão bem.
// 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' );
Encontre inconsistências usando grep na sua base de código:
grep -rE "__\(|_e\(|_n\(|_x\(" --include="*.php" .
Observe o último argumento de cada correspondência. Todos eles devem ser o text domain do seu plugin. Se você encontrar erros de digitação ou de copiar e colar, corrija-os e execute wp i18n make-pot novamente para atualizar o .pot.
Para código JavaScript usando @wordpress/i18n, a mesma regra se aplica. O wp_set_script_translations() no PHP também deve passar o domínio correspondente:
wp_set_script_translations( 'my-plugin-editor', 'my-plugin', '...' );
// ^^^^^^^^^^^
// Must match the JS calls
Detecte os mesmos problemas antes do lançamento com o AI Visual QA
O ciclo de diagnóstico acima é reativo. Uma tradução está ausente, você vai à caça da causa. O AI Visual QA da PTC detecta os mesmos problemas antes do lançamento. Ele inspeciona o plugin renderizado em cada idioma de destino após cada atualização de tradução e relata o que está ausente ou errado.
Para uma string em inglês hardcoded fora de __() (Causa 1 acima), o AI Visual QA vê a string não traduzida no plugin renderizado. A PTC gera um prompt pronto para colar para o Cursor ou Claude Code para envolver a string em __(). Para uma incompatibilidade de text domain (a verificação da seção anterior), ele vê a string não traduzida quando outras strings na mesma tela estão traduzidas, e relata a inconsistência.
Se você ainda não ativou o AI Visual QA, veja o tutorial de temas e plugins do WordPress para a configuração.
Quando as quatro verificações passam e as traduções ainda estão ausentes
Se você executou todas as quatro verificações e as traduções ainda não estão aparecendo, envie um e-mail para o suporte da PTC com:
- O text domain do seu plugin.
- Um dos nomes de arquivo
.mo(por exemplo,my-plugin-es_ES.mo). - Uma captura de tela do painel da PTC mostrando a string afetada com a sua tradução.
- A configuração de idioma do site em Configurações > Geral.
A maioria dos casos de “tradução ausente” se resume a uma das causas acima. Casos extremos (versões específicas do WordPress, resolução de locale em MultiSite, conflito com outro plugin de i18n) às vezes precisam de uma segunda análise.
Mantenha os lançamentos futuros sincronizados com a localização contínua
Assim que as suas traduções carregarem corretamente, configure o fluxo de trabalho de localização contínua para que os lançamentos futuros fiquem sincronizados com as suas traduções - automaticamente, a cada push para a main.