Estrutura de Internacionalização do EtherWallet
O EtherWallet utiliza uma arquitetura de internacionalização (i18n) robusta para oferecer suporte a 18 idiomas diferentes. O sistema foi projetado para separar completamente o conteúdo textual da lógica de negócios, facilitando a manutenção e a inclusão de novas traduções por membros da comunidade.
A base dessa implementação reside em três pilares fundamentais: arquivos de recursos isolados, um motor de processamento centralizado e a integração reativa na interface do usuário.
Organização dos Arquivos de Tradução
As definições de linguagem estão localizadas no diretório app/scripts/translations/. Cada idioma é representado por um arquivo JavaScript individual que exporta um objeto contendo chaves e valores. Essa abordagem evita arquivos de configuração gigantescos e melhora a organização.
Exemplo de estrutura de um arquivo de idioma (pt.js):
const portuguese = {
"UI_Welcome_Msg": "Bem-vindo à sua carteira Ethereum",
"BTN_Send_Ether": "Enviar Ether",
"ERR_Invalid_Address": "O endereço inserido é inválido.",
"INFO_Backup_Wallet": "Certifique-se de fazer **backup** da sua chave privada!"
};
module.exports = portuguese;
Motor de Tradução e Configuração do Provedor
O gerenciamento das traduções é feito através de um serviço central que utiliza o $translateProvider (comumente associado ao ecossistema AngularJS, no qual o EtherWallet foi construído). Este serviço carrega os pacotes de idiomas e define as regras de fallback.
const configureI18n = ($translateProvider) => {
// Carregamento de pacotes de idiomas
const langEn = require('./en');
const langPt = require('./pt');
const langEs = require('./es');
// Registro das traduções processadas com suporte a Markdown
$translateProvider.translations('en', applyMarkdown(langEn));
$translateProvider.translations('pt', applyMarkdown(langPt));
$translateProvider.translations('es', applyMarkdown(langEs));
// Configuração de idioma padrão e reserva
$translateProvider.preferredLanguage('en');
$translateProvider.fallbackLanguage('en');
};
Um diferencial importante é a função applyMarkdown. Como muitas strings de ajuda no EtherWallet contêm formatação (negrito, links), o sistema processa os valores das traduções através de um parser de Markdown antes de registrá-los no provedor.
function applyMarkdown(translationSet) {
const processedData = {};
for (let key in translationSet) {
if (translationSet.hasOwnProperty(key)) {
processedData[key] = marked(translationSet[key]);
}
}
return processedData;
}
Implementação na Camada de Visualização
A aplicação consome essas traduções de forma declarativa nos templates HTML ou programática nos controladores.
Uso nos Templates HTML
Através de filtros, o desenvolvedor referencia a chave da tradução, permitindo que a interface mude instantaneamente quando o usuário altera o seletor de idiomas.
<section>
<h2>{{ 'UI_Welcome_Msg' | translate }}</h2>
<button>{{ 'BTN_Send_Ether' | translate }}</button>
</section>
Uso nos Controladores
Quando mensagens dinâmicas (como alertas de erro) são necessárias, o serviço de tradução é injetado diretamente no código JavaScript.
function TransactionController($scope, $translate) {
$scope.validateAndSend = function(address) {
if (!isValid(address)) {
$translate('ERR_Invalid_Address').then(function(translatedText) {
alert(translatedText);
});
}
};
}
Gerenciamento de Preferências e Persistência
Para garantir que a escolha do usuário seja mantida em sessões futuras, o EtherWallet utiliza o localStorage do navegador. Quando o idioma é alterado, o estado global é atualizado e a nova perferência é armazenada.
$scope.updateLanguage = function(newLangCode) {
$translate.use(newLangCode);
window.localStorage.setItem('user_language', newLangCode);
};
Padronização de Chaves de Tradução
Para manter a escalabilidade com 18 idiomas, o projeto adota uma convenção de nomenclatura rigorosa para as chaves:
- Prefixos de Contexto: Indica onde a string é usada (ex:
NAV_para navegação,SIDEBAR_para barra lateral). - Descritores Funcionais: Nome curto em inglês que descreve o propósito (ex:
_Save_Button). - Indexação: Útil para sequências de instruções ou parágrafos longos.
Vantagens desta Abordagem
Este modelo de arquitetura oferece benefícios claros para projetos de código aberto:
- Desacoplamento: Tradutores não precisam entender o código-fonte, apenas editar os arquivos
.jsde recursos. - Performance: O carregamento é eficiente e a troca de idioma ocorre sem recarregar a página.
- Consistência: O uso de chaves garante que o mesmo termo técnico seja usado uniformemente em toda a aplicação.