IA & Tecnologia

Porque é Que os Ficheiros de Localização Traduzidos Estragam as Aplicações (e o Que Tem de Ficar Intacto)

set 23, 2026

Porque é Que os Ficheiros de Localização Traduzidos Estragam as Aplicações (e o Que Tem de Ficar Intacto)

Um Ficheiro de Localização É Código com Frases Lá Dentro

Os ficheiros de idioma PO, YAML, .properties, RESX, XLIFF e JSON parecem listas de frases, mas só os valores são prosa. As chaves são identificadores que o código procura; os marcadores de posição são espaços que o código preenche em tempo de execução; os escapes e a marcação são sintaxe da qual o analisador depende. Um tradutor que trate a linha inteira como texto produzirá um ficheiro que se lê muito bem e não carrega, ou que carrega e depois falha na primeira vez que um ecrã formata um número. A falha costuma surgir num único idioma, o que faz dela o tipo de erro mais difícil de apanhar numa revisão.

Cinco Coisas Que Têm de Sobreviver à Tradução Sem Alterações

  • Chaves e nomes de recursos — o código procura as cadeias pela chave, por isso uma chave traduzida é simplesmente uma cadeia em falta.
  • Marcadores de posição — %s, %1$d, {0}, {name} e os argumentos ICU são preenchidos pelo código; mudar o nome de um deles ou removê-lo estraga a formatação ou gera um erro em tempo de execução.
  • Escapes e regras de codificação — um ficheiro .properties lido com o método clássico Properties.load(InputStream) é tratado como Latin-1, com os restantes caracteres escritos como escapes \uXXXX, pelo que texto não latino em bruto pode transformar-se em mojibake.
  • Marcação dentro das cadeias — as etiquetas HTML, os códigos inline do XLIFF e o Markdown têm de ficar equilibrados, ou a cadeia apresentada estraga a página à sua volta.
  • Estrutura do ficheiro — a indentação YAML, os escalares de bloco, as âncoras e aliases e o aninhamento XML são sintaxe; uma indentação deslocada ou um nome de âncora traduzido altera o significado do ficheiro.

Os Plurais Não São um Singular Mais um "s"

O inglês tem duas formas de plural, por isso é tentador pensar que todos os idiomas também têm. O manual do GNU gettext mostra porque é que isso falha: cada idioma declara a sua própria regra Plural-Forms, o inglês usa nplurals=2 e o russo precisa de três formas escolhidas pelos últimos algarismos do número. Um ficheiro PO traduzido para russo com apenas duas formas preenchidas compila, executa e imprime a gramática errada para cada contagem terminada em 2, 3 ou 4. Tratar corretamente os plurais significa produzir o número de entradas msgstr que o idioma de destino exige, e não o número que o idioma de origem por acaso tinha.

Por Vezes os Marcadores de Posição Têm de Mudar de Lugar

A ordem das palavras difere entre idiomas, por isso uma frase com dois valores tem muitas vezes de os colocar pela ordem inversa. Os marcadores posicionais como %1$s e %2$s, ou os nomeados como {count} e {user}, existem precisamente para isso: a tradução pode reordená-los, mas cada um tem de continuar presente exatamente uma vez. Os marcadores anónimos, como um %s simples, não podem ser reordenados com segurança — um problema que vale a pena corrigir nas cadeias de origem antes da tradução, e não depois.

Regras de Formato a Conhecer Antes de Traduzir

Cada formato tem as suas armadilhas. Em YAML, a especificação dá a um bloco literal (|) e a um bloco dobrado (>) comportamentos diferentes nas quebras de linha, e as âncoras (&) e aliases (*) permitem que um nó reutilize outro, por isso ambos têm de passar intactos. O XLIFF 2.1 envolve a formatação original em elementos inline como <ph> e <pc>, que a tradução tem de manter no sítio, à volta das palavras certas. Em .NET, os recursos RESX são procurados pelo nome em tempo de execução para a cultura da interface atual, por isso um elemento data renomeado recorre silenciosamente ao idioma predefinido. E um ficheiro .properties de Java trata o primeiro =, : ou espaço em branco sem escape como separador da chave, por isso uns dois pontos perdidos numa chave traduzida dividem-na em duas.

Uma Lista de Verificação Que Apanha a Maioria das Falhas

  1. Conte os marcadores de posição em cada cadeia de origem e de destino — o multiconjunto tem de coincidir, mesmo quando a ordem não coincide.
  2. Compare as chaves, não os valores — qualquer chave presente na origem e em falta ou renomeada no destino é um erro.
  3. Carregue o ficheiro traduzido com o analisador real (msgfmt, um carregador YAML, ResXResourceReader) antes de o publicar.
  4. Verifique as entradas de plural face à regra do idioma de destino, não do idioma de origem.
  5. Apresente a tradução mais longa no elemento de interface mais apertado — o texto noutros idiomas ocupa muitas vezes mais espaço do que o inglês.
Porque é que uma aplicação falha num idioma mas não nos outros?

Quase sempre porque um marcador de posição foi alterado apenas nesse idioma — renomeado, removido ou duplicado. O código passa os mesmos argumentos a todos os idiomas, por isso a única tradução que já não corresponde a eles falha quando esse ecrã é formatado.

Porque é que o russo precisa de três cadeias de plural quando o inglês precisa de duas?

As regras de plural pertencem ao idioma, não ao software. O gettext permite que cada idioma declare a sua própria regra; o russo escolhe entre três formas com base nos últimos algarismos do número, por isso uma tradução com apenas duas formas imprime a gramática errada para muitas contagens.

Porque é que os caracteres acentuados se transformam em lixo num ficheiro .properties de Java?

Porque o clássico Properties.load(InputStream) lê o ficheiro como Latin-1. Os caracteres fora desse intervalo têm de ser escritos como escapes \uXXXX, ou o ficheiro tem de ser carregado com um leitor que use a codificação certa.

Uma tradução pode mudar a ordem dos marcadores de posição?

Sim, quando são posicionais (%1$s, %2$s) ou nomeados ({count}, {user}) — reordenar é muitas vezes necessário para uma ordem natural das palavras. Cada marcador tem ainda de aparecer exatamente uma vez. Os marcadores %s simples não podem ser reordenados com segurança.

Porque é que as chaves nunca devem ser traduzidas?

As chaves são identificadores, não texto. O código pede uma cadeia pela sua chave; uma chave traduzida significa que a procura falha e a aplicação mostra uma chave em bruto ou recorre ao idioma predefinido.

Traduza os Valores, Mantenha o Código

Carregue um ficheiro PO, YAML, .properties ou RESX e receba-o de volta com as chaves, os marcadores de posição, os escapes e a estrutura exatamente onde estavam.

Traduzir um Ficheiro de Idioma Grátis