Você já achou um blog bacana, rico em conteúdo, cheio de coisa interessante, na sua língua pátria e quando chegou no final da página leu coisas como "3 comments" ou "posted by Rodrigão on feb-11". Se você for parecido comigo, deve ter achado isso ridículo...

Bom, em geral isso acontece por falta de conhecimento ou mesmo preguiça de quem criou o site. Nesse mundo globalizado, de acesso livre pela internet, e constante troca de informações entre pessoas de vários países, as chances são muito altas de que ao criar seu blog você use um pedaço de software escrito em outro idioma. Perfeitamente normal, o próprio WordPress é 100% escrito em Inglês.

O pior acontece quando, por omissão ou preguiça, pequenos ajustes não são feitos. E quando esse pedaço de software não ajustado ocorre de ser um Tema WordPress, ou o plugin principal do seu blog, o resultado é seu usuário final vendo mensagens em outro idioma que não o mesmo do site.

Isso é ruim de várias formas! Primeiro, frusta o usuário que não entende aquele idioma (ou ao menos pode confundi-lo). Segundo, os buscadores enxergam essa palavras mal colocadas como falhas, e ninguém vai me convencer que esse não é um dos sinais de posicionamento (tudo bem que um bem fraquinho).

Mas então, como fazer para corrigir esse problema, sem encher o desenvolvedor de golpes mortais na cabeça?

Veja o vídeo

Escrevendo código localizável

Bom, a solução varia um pouco. Em primeiro lugar, é preciso saber que existe uma certa “etiqueta” para se escrever código compatível com WordPress. Quero dizer, existe um "jeito certo" de se escrever temas, plugins e outras coisas para chamá-las de compatíveis com o WordPress. E parte dessa etiqueta reza que toda sentença ou mensagem para o usuário final deve ser encapsulada por uma chamada ao sistema tradutor do WordPress, de modo que o integrador tenha a opção de traduzir tal mensagem para seu idioma, e também para que um pacote de tradução possa ser criado para seu software.

Vejamos um exemplo simples. Suponha um plugin que lide com formulário de contato, e que quando a mensagem é registrada com sucesso exiba uma mensagem de sucesso. Agora, digamos que o autor é australiano, e tenha escrito o seguinte código:

if ($form_status == 'success') echo "Yeah Mate! Message received.";
else echo "Something went wrong, mate!";

Esse código tem efeito direto no seu blog, afinal quando o usuário preencher o formulário e enviar, verá uma dessas duas mensagens. Se meu pai usasse tal formulário ia achar que deu tudo errado (e estaria certo 50% das vezes hehe). O que a etiqueta do WordPress diz sobre isso é que esse trecho de código deveria ser reescrito com chamadas ao núcleo de tradução do WordPress, que usa o GNU GetText, que podemos resumir como uma série de sentenças agrupadas em domínio. Isso pode ser feito, por exemplo, da seguinte forma:

if ($form_status == 'success') _e("Yeah Mate! Message received.", 'contact-form');
else _e("Something went wrong, mate!", 'contact-form');

Este código faz exatamente a mesma coisa que o anterior, com a mesma mensagem inclusive, mas agora existe um domínio declarado contact-form, no qual pelo menos duas sentenças estão declaradas. O GetText fornece meios de analisar o código fonte procurando por chamadas às funções _e() e __(), e assim criar um arquivo POT que é uma tabela-padrão das sentenças declaradas em um domínio específico. A partir desse arquivo POT, há ferramentas que permitem gerar um arquivo PO, que nada mais é que um arquivo texto parecido com isso aqui:

"PO-Revision-Date: 2016-03-20 21:19:43-0300\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: GlotPress/1.0-alpha-1100\n"
"Project-Id-Version: Administration\n"
#: wp-content/inc/form.php:101
msgid "Yeah Mate! Message received."
msgstr ""
#: wp-content/inc/form.php:102
msgid "Something went wrong, mate!"
msgstr ""

Esse arquivo tem informações bem interessantes. Primeiro, ele é direcionado a um único idioma, logo podem (devem!) existir vários arquivos PO em um projeto, um para cada idioma. Segundo, ele menciona os arquivos e linhas do código-fonte onde as chamadas foram feitas para cada sentença. Isso permite uma análise contextual da mensagem, caso seu objetivo não seja imediatamente claro. Por fim, note que há uma linha com o "comando" msgid, sempre seguida de uma com o "comando" msgstr. Isso determina um par de tradução, sendo msgid a mensagem original no código-fonte, e msgstr a equivalente no idioma do arquivo, ou seja, sua tradução. Olha que maravilha: uma simples reescrita no código permite a um desenvolvedor usar mensagens em seu próprio idioma (seja ele qual for) sem trabalho extra, e ao mesmo tempo permite que outras pessoas as traduzam e tornem seu código ainda mais útil e aproveitável.

Mas será mesmo preciso lidar com esse arquivo PO maluco? Bom, sim, até certo ponto. O arquivo PO é crucial, porque dele podemos compilar um arquivo MO, que é o que de fato o WordPress (o GetText na verdade) utiliza para a tradução. Existem ferramentas para se fazer isso, mas eu considero a mais útil de todas um plugin para WordPress chamado Loco Translate.

Traduzindo com o plugin Loco Translate

O Loco Translate lida com todos estes aspectos discutidos: leitura do POT, edição do PO e compilação do MO. E permite fazer tudo isso do próprio admin do WordPress, com retorno imediato inclusive (salve e veja a tradução aplicada na hora). Ele faz até mais um pouco: quando não há o arquivo POT disponível, ou quando ele está desatualizado (omissões, omissões...), o Loco consegue ele mesmo analisar o código-fonte e encontrar as chamadas de tradução, resultando assim numa tabela atualizada de tudo o que pode ser traduzido em um plugin ou tema qualquer. Ah! e ele ainda salva os arquivos no lugar certo, conforme esperado pelo WordPress, para que tudo funcione. De fato, há pouquíssimas coisas nesse mundinho de traduções que o Loco não consegue fazer, e estas em geral são atreladas a códigos de baixa qualidade (i.e. códigos que não seguem a etiqueta do WordPress).

Como exemplo prático ilustrativo, e na verdade meio que o motivo que me deu a ideia desse artigo, considere uma versão anterior deste meu blog aqui. Quando o criei eu achei um tema legalzinho chamado Gravit. Ele me pareceu útil, mas estava todo em inglês. Então eu ativei o plugin Loco Translate, e ele já enxergou o Gravit, no caso sem nenhuma tradução disponível e nem mesmo um arquivo POT criado. Ainda assim, o loco conseguiu analisar o código e encontrou 70 sentenças, que eu traduzi em poucos minutos e salvei. Na hora, meus posts e rodapé já estavam em Português!

Se o desenvolvedor do Gravit fosse um pouco mais caprichoso, teria usado as chamadas convenientes também na parte do Tema que lida com sua tela de Personalização. Assim, coisas como Global Options e Show Post Icons, que somente o administrador enxerga, poderiam também estar em bom Português, facilitando a utilização do tema mundo afora. Aliás, se ele tivesse feito isso, poderia ter dado um passo além e criado na descrição do tema (que aparece no Repositório WordPress) uma instrução para o envio de arquivos PO traduzidos, e como a comunidade WordPress é bem prestativa, ele em não muito tempo teria algumas dezenas de traduções, parciais ou completas, para aumentar a atratividade do tema.

Aspectos técnicos da tradução em WordPress

Para fechar esse assunto, acho conveniente explicar alguns termos, de forma bem rapidinha. Primeiro, o trabalho de tradução em si não é tão direto quanto se poderia pensar, e existem alguns nuances que valem a pena citar:

Internacionalização (i18n)

Internacionalization (ou i18n) é o processo de transformação de um conteúdo escrito em um idioma para um equivalente escrito em outro. Compreende basicamente uma tradução literal ou mecânica em um par de idiomas. É o que as pessoas em geral entendem como tradução, e é isso que geralmente se faz no WordPress. Ex: a frase “nothing was found” é traduzida literalmente como “nada foi encontrado”. Como se poderia prever, isso basta na maioria dos casos.

Curiosidade: o termo i18n é muito usado por desenvolvedores, e é uma forma curta de escrever o palavrão (no sentido de palavra grande mesmo) internacionalization, que começa com i, termina com n e tem 18 letras no meio, logo i18n.

Localização (l10n)

Localization (ou l10n) é o processo de adaptar um conteúdo para outra cultura, mais do que simplesmente traduzir em outro idioma. Permite fazer ajustes na abordagem ou apresentação de forma que diferenças culturais possam ser consideradas e o conhecimento possa ser de fato absorvido.

É usado em níveis mais altos de internacionalização, por exemplo, em sites de multinacionais com presenças em países com idiomas variados. Ao invés de ter um “clone traduzido” do site original em cada idioma (típico i18n), é mais proveitoso para essa empresa ter uma “versão local” em cada país, cada uma no idioma certo e com notícias e conteúdos mais localizados, não necessariamente iguais aos disponíveis nos demais países.

A Localização também faz uso mais livre de expressões idiomáticas, colóquios e regionalismos.

Códigos de Idioma

Os idiomas possuem códigos normatizados pela ISO, com aplicação mundial, que designam as variantes de cada idioma, em geral associando-as aos países. Por exemplo, o idioma Português tem o código pt, mas como há vários países falando Português, cada um do seu jeito, usamos os códigos pt_BR para Português Brasileiro, pt_AO para o Angolano e pt_PT para o de Portugal. Isso permite ser muito mais preciso na tradução, evitando por exemplo usar as palavras Ecrã e Telemóvel no Brasil, que só entende Tela e Celular.

Os arquivos PO e MO utilizados em geral seguem a nomenclatura dominio-xx_YY, ou seja, o domínio seguido do idioma no formato ISO. Pode-se considerar ainda um arquivo dominio-xx que atenda à todas as versões do idioma que não tiverem um arquivo dedicado. Logo, podemos aproveitar por exemplo a primeira tradução para Português seja de qual país for, como simplesmente "português", e ela certamente será mais útil à cada país do que o inglês ou espanhol.

Sentenças

Sentenças são as unidades de informação traduzíveis, que na maioria dos casos são Strings. Quando a String é fixa, tudo é muito óbvio (como nos exemplos acima). Mas elas também podem ser bem complicadas, por exemplo envolvendo código HTML ou mesmo variáveis de substituição. Como exemplo, as 3 Strings abaixo são todas perfeitamente válidas, mas progressivamente mais complicadas de traduzir (isto é, mais propensas ao erro):

  • Hello World
  • Hello %1$s, my name is %2$s
  • Hello <strong>%1$s</strong>&rarr; my name is <a href=”%3$s” rel=”author”>%2$s</a>

Cabe ao desenvolvedor ter o critério de simplificar as sentenças sempre que possível, reduzindo os erros de tradução. Um caso típico de redução de complexidade é não usar uma sentença com todo o link HTML, mas sim usar uma construção de link que aproveita 2 ou mais sentenças, conforme necessário. Assim cada uma delas fica mais simples.

Domínios

Domínio são agrupamentos de sentenças pertencentes a um mesmo escopo no código-fonte, por exemplo, o mesmo plugin, módulo ou tema. Novamente, é o desenvolvedor quem determina os domínios, e pode inclusive optar por usar mais de um. Também é possível que um plugin tenha um domínio principal e outros secundários, oriundos de códigos de terceiro dos quais o plugin depende. Hoje em dia é muito comum os temas terem uma boa base de tradução, porém utilizarem algo como o Redux para gerenciar suas opções, sem contudo fornecer os domínios corretos para a tradução delas. O resultado é um tema bem traduzido na frente do site, mas com o painel administrativo todo em inglês (às vezes mal escrito, ainda por cima).

Arquivo POT

Arquivos POT são como uma tabela matriz com tudo o que o domínio oferece para ser traduzido. Só existe um POT por domínio, e ele não contém nenhuma tradução de fato, apenas os textos originais. Ele é na verdade um modelo para os arquivos PO usados na tradução para cada idioma-alvo.

Manter o arquivo POT atualizado é uma "obrigação" do desenvolvedor competente, mas isso e com frequência esquecido ou ignorado pela maioria. Ferramentas como o Loco Translate permite comparar o POT com o PO e assim sincronizar a tradução, por exemplo adicionando novas sentenças e removendo sentenças não mais utilizadas.

Arquivo PO

O arquivo PO é a primeira derivação do POT original (embora possa existir sem um POT também), e representa a série de pares de tradução entre o idioma original e o idioma alvo. Não há nenhuma obrigação do idioma original ser o Inglês, isso é apenas o caso mais comum. Se você escreve códigos em espanhol, pode perfeitamente fornecer POT e PO com originais em espanhol: isso apenas exigirá que a tradução para Francês deverá ser feita por alguém que fale Espanhol e Francês. Na prática é assim mesmo que acaba acontecendo, uma tradução nova nasce não diretamente do POT original, mas do PO de um outro idioma semelhante ou melhor entendido pelo tradutor.

Arquivo MO

O arquivo MO é um arquivo-objeto compilado de um PO, e pode ser visto como um pequeno banco de dados com o mapeamento de cada sentença original no texto traduzido equivalente. O arquivo MO não deve ser editado manualmente, mas somente pelas ferramentas e compiladores apropriados. A existência do arquivo MO é puramente uma eficiência computacional: ele é otimizado para a leitura, e dispensa toda a interpretação lexigráfica e semântica que o PO precisaria para servir como fonte de sentenças.

Na prática e usando boas ferramentas, o arquivo MO é transparente para o tradutor, sendo compilado automaticamente a cada mudança no PO original. Mas é preciso reconhecer suas implicações, pois ele pode criar uns atrasos na percepção da tradução quando um cache está em uso, por exemplo.

Conclusão

Por fim, acho muito útil dar uma palavrinha sobre dois aspectos finais da tradução em WordPress: onde os arquivo PO/MO devem ficar, e quem deve ser responsável por eles. Estes dois aspectos estão intimamente ligados.

Primeiro, é muito mais conveniente para o usuário final do código (em geral, o dono do site) que as traduções sejam fornecidas junto com o código, mesmo que não tenha sido o autor quem as tenha criado. O WordPress faz isso, assim como alguns de seus plugins mais famosos: você instala o WooCommerce e ele simplesmente está no seu idioma. Para que isso ocorra, o arquivo MO deve ficar na pasta languages na raíz do plugin (ou tema). É lá que o WordPress irá procurar por ele, e embora outras configurações sejam possíveis, requerem ações extras. O nome do arquivo deve ser padronizado, no estilo dominio-xx_YY.mo, onde o domínio em geral é o nome do plugin. Note que, para funcionar, basta ter os arquivos MO posicionados. O POT e os POs só são úteis quando se quer traduzir, e não precisam necessariamente fazer parte da distribuição.

Existe um segundo lugar muito importante, que é a pasta wp-content/languages do seu WordPress. Os arquivos MO nesta pasta tem maior prioridade do que os na pasta do plugin/tema, e isso é precisamente para permitir que você sobrescreva a tradução de um tema ou plugin com sua própria versão. Alguns temas e plugins nem distribuem mais as traduções, mas indicam ao WordPress onde encontrá-las e então baixar para esta pasta. O WooCommerce, por exemplo, trabalha assim, e é este o motivo pelo qual depois que você atualiza o plugin, ocasionalmente recebe uma mensagem dele avisando que a tradução no seu idioma está desatualizada.

Pronto! Falei o que tinha pra falar sobre isso. Agora, se você meu amigo (ou amiga!) conseguir finalizar o trabalho de traduzir um tema, plugin ou outra coisa que lhe foi útil, dê o próximo passo e disponibilize a tradução para as outras pessoas. Isso em geral é fácil, basta entrar em contato com a equipe de desenvolvimento e enviar os arquivos PO/MO para eles. A maioria das equipes terá prazer em receber e ainda lhe dará uma linha de crédito no site ou página deles.