No
artigo a seguir, examinaremos os principais componentes
internacionalizados de um aplicativo Web e detalharemos
alguns princípios comuns a todos os esforços
de internacionalização de software.
Esse aplicativo, criado em Java com um back-end
Oracle, foi desenvolvido inicialmente pela Zia
Consulting (http://www.ziaconsulting.com) e fornece cotações
de equipamentos para indivíduos em 27 países.
As bibliotecas de software citadas neste artigo
são do padrão Java; outras linguagens
podem ter ou não o mesmo nível de
suporte.
Os
três aspectos principais envolvidos na internacionalização
de um aplicativo são:
- encontrar
a localidade preferencial do usuário
dentro do conjunto de localidades disponíveis
- exibir
informações adequadas à
localidade escolhida
- questões
operacionais
Observe
que a internacionalização é
apenas metade do processo — quando o aplicativo
é capaz de lidar com localidades diferentes,
deve-se fornecer a ele as informações
e os dados específicos a cada uma delas.
Esse processo se chama “localização”,
e este artigo não abordará esse
assunto.
Encontrando
a localidade apropriada
Em primeiro lugar, um usuário deve ser
associado a uma localidade. Trata-se de uma configuração
como outra qualquer. É essencial permitir
que o usuário escolha explicitamente a
localidade adequada. Há algumas dicas que
o computador do usuário pode fornecer:
no Microsoft Windows, existe uma chave “Country”
no Registro¹, e os navegadores podem fornecer
as preferências de uma localidade específica
e comunicá-las ao servidor, em um processo
chamado “negociação de idioma” (http://www.w3.org/, em inglês).
No
entanto, embora isso possa servir como ponto de
partida para um item de software, certamente não
é a resposta completa. O sistema operacional
pode estar configurado incorretamente, ou o usuário
pode estar no cibercafé de um país
estrangeiro, com as configurações
adaptadas para o usuário típico
do lugar, mas não para ele.
Quando
a localidade de um aplicativo não está
definida corretamente, o usuário típico
culpa o aplicativo e não o sistema operacional
ou o navegador. E, ao contrário de outras
opções de configuração,
é comum inutilizar um aplicativo pela escolha
incorreta da localidade. Existem também
requisitos comerciais que exigem que o usuário
escolha sua localidade, independentemente da configuração
da máquina.
Por
exemplo, no sistema de cotações
ao qual se refere este artigo, os usuários
talvez precisem receber a cotação
em dólares norte-americanos. Isso ocorre
com freqüência quando empresas multinacionais
têm uma entidade de compras que lida apenas
com cotações em dólar.

Caixa de diálogo de instalação
de localidade no GFTPKlient
Em
resumo, o melhor método para descobrir
a localidade mais adequada a um usuário
é perguntar. Em aplicativos de desktop,
isso geralmente ocorre no momento da instalação,
como indicado na ilustração acima.
Em um aplicativo Web, é um pouco mais complexo,
mas geralmente ele não deve solicitar a
localidade de preferência caso reconheça
que a solicitação veio de um usuário
cuja localidade preferencial já é
conhecida. Ao perguntar claramente ao usuário,
o aplicativo demonstra estar preparado para lidar
com várias localidades e permite que o
usuário escolha uma localidade adequada,
independentemente das configurações
existentes.
Naturalmente,
temos aqui um problema de inicialização:
em que idioma deve ser colocada a consulta inicial
sobre localidade? Existem duas opções:
use um “mínimo denominador comum” - um
idioma que seja amplamente conhecido pelo público-alvo
- ou use uma imagem com instruções
simples em vários idiomas. O motivo de
usar uma imagem em vez de texto é que os
usuários talvez não tenham fontes
instaladas para todos os idiomas aceitos. Além
disso, a aparência de uma imagem é
melhor do que uma série de pontos de interrogação,
que é como alguns sistemas operacionais
exibem os caracteres que não reconhecem.
No
entanto, o uso de imagens tem um custo. Quando
você tiver de atualizar e recolocar a mensagem,
sairá mais barato fazer com que alguém
modifique um trecho isolado do texto. Trabalhar
com imagens é mais caro e mais complicado;
alguém precisa fornecer o novo texto, e
a imagem existente precisa ser modificada, geralmente
por um especialista em artes gráficas.
Se a imagem for modificada no tamanho ou na forma,
o departamento de controle de qualidade (também
conhecido como “QA”, do inglês Quality Assurance), deve se assegurar
de que os caracteres inalterados não tenham
sofrido modificações.
Além
das considerações de custo, a opção
pela “inicialização de localidade”
para um aplicativo depende muito do público-alvo.
Para um aplicativo científico na Web, pode
até ser seguro usar o inglês nas
instruções iniciais; entretanto,
um aplicativo de prateleira talvez precise de
um texto simples de inicialização,
traduzido para vários idiomas. O aplicativo
de cotações, como indicado abaixo,
usa as duas opções – para usuários
desconhecidos, usa um padrão de localidade
em inglês norte-americano (como demonstrado
pelo texto “If your country...”) e, ao mesmo tempo,
transporta esses usuários para uma página
com mensagens em vários idiomas que pedem
que ele “Selecione seu país”. (O motivo
de usar “país” em vez de “localidade” nessa
mensagem é que os usuários típicos
não têm idéia do significado
exato de localidade.)

O selecionador de localidades do aplicativo de cotações
Para
obter a maior compatibilidade possível,
seja qual for a escolha do usuário, a localidade
deve ser armazenada usando os códigos de
país e de idioma ISO (International Organization
for Standardization). Java usa o código
de idioma com duas letras minúsculas seguidas
de um espaço sublinhado e do código
do país, também com duas letras,
em maiúsculas². Por exemplo, en_US significa inglês norte-americano, enquanto
pt_BR
quer dizer português
brasileiro. O aplicativo Web de
cotações usou vários códigos
de localidade, principalmente visando à
compatibilidade com produtos mais antigos. Essa
decisão causou alguns problemas quando
novos produtos de software internacionalizados
foram integrados ao site – foi preciso escrever
uma camada de tradução. Se for possível,
opte por armazenar as informações
de localidade no formato padrão.
Depois
que o usuário já tiver escolhido
a localidade, o aplicativo não deverá
mais solicitá-la. Em um software de desktop,
isso não é problema, uma vez que
o desenvolvedor deve armazenar o valor escolhido
no Registro ou em um arquivo de configuração.
No entanto, em um software para a Web, é
inevitável perguntar novamente. Se o usuário
apagar seus cookies ou visualizar o aplicativo
em outro computador, o servidor não poderá
identificá-lo. Isso significa que a escolha
da localidade deve ser a mais fácil possível
em um aplicativo Web, pois é provável
que ocorra com mais freqüência do que
em um aplicativo de desktop.
Mas
o usuário deve ser capaz de reconfigurar
o aplicativo e escolher uma nova localidade. Apesar
de o Windows permitir que os usuários adotem
uma nova localidade sem necessidade de reinstalação,
na prática, é comum os aplicativos
de desktop típicos não oferecerem
essa opção. Por outro lado – e por
serem criados para lidar com usuários transitórios
– os aplicativos Web devem ter maneiras fáceis
de alterar a localidade de preferência.
No aplicativo de cotações, por exemplo,
cada página tem uma caixa suspensa em que
o usuário pode selecionar outra localidade.
Apresentando
informações específicas à
localidade
Depois que o usuário tiver feito sua escolha,
o aplicativo deve responder mostrando informações
pertinentes à localidade. O tipo de informação
mais importante é o idioma do texto exibido.
Outras informações específicas
à localidade são: regras comerciais
– se será mostrado ou não um produto
que pode ser ilegal ou que não esteja disponível
em determinado país –, classificação
alfanumérica e formatação
de datas e números. Examinaremos cada uma
dessas opções no contexto do aplicativo
de cotações.
A
maneira comum de colocar na interface do aplicativo
o texto adequado a uma localidade é garantir
que todo o texto da interface foi substituído
por tokens. Cada token é uma string de
chave usada quando o desenvolvedor está
criando a interface do usuário. O aplicativo
de cotações a que nos referimos
como exemplo usou JSPs (Java Server Pages) e bibliotecas
de tags, mas esses conceitos aplicam-se a quase
todas as tecnologias de exibição.
Em arquivos separados, pelo menos um para cada
localidade, a chave recebe um valor localizado.
O
valor deve ser armazenado com uma representação
UTF (Unicode Transformation Format), que pode
usar vários bytes para representar um único
caractere. Cada linguagem de programação
lida com essa representação de um
modo bem específico. No caso de Java, os
caracteres UTF são geralmente tratados
como caracteres de escape e armazenados no conjunto
ISO-8859-1 (para obter mais informações
a respeito, visite http://java.sun.com/).
Uma
seqüência UTF de escape tem o seguinte
aspecto: \u65e5. Depois que o usuário
identifica a localidade preferencial, o aplicativo
(representado pela caixa “Estrutura” na ilustração
abaixo) gera a interface correta substituindo
todas as chaves pelos valores correspondentes,
que são extraídos de um arquivo
ou banco de dados (a “Área de armazenamento
de dados”, abaixo). Presume-se que o sistema do
usuário esteja configurado corretamente
(com as fontes etc.) para a localidade escolhida.

Muitas
linguagens modernas de programação
têm suporte a bibliotecas para essa separação
entre valores e chaves, inclusive Java e XUL (XML
User Interface Language, parte da estrutura dos
aplicativos Mozilla). Se você estiver criando
um aplicativo internacionalizado e puder escolher
uma linguagem de desenvolvimento, é altamente
recomendado que você examine os recursos
de internacionalização de cada uma
das linguagens de programação consideradas,
pois algumas contam com melhor suporte do que
outras.
Um
exemplo de um par valor/chave para localidade
inglês norte-americano é:
HELLO_KEY=Hello there!
Extrair
todo o texto presente na interface do usuário
é um trabalho tedioso, embora seja possível
usar alguma automação. Esse é
um motivo importante para internacionalizar o
aplicativo desde o início, pois é
mais fácil garantir que houve extração
de todo o texto quando se faz isso já no
começo: o aplicativo tem menos complicadores,
e os recursos ou componentes adicionais podem
ser internacionalizados um a um.
Nesse
ponto, o desenvolvedor deve começar a analisar
também o processo de localização:
como traduzir, testar e implantar com eficácia
todo o texto? No caso de textos armazenados em
arquivos, o aplicativo de cotações
usou uma combinação de planilhas
Excel para entrada de dados, um banco de dados
Access para armazenar todas as strings localizadas
e vários scripts para extrair e gerar arquivos
a serem usados pelo aplicativo Web.
Além
da mera substituição do valor da
chave, talvez convenha colocar conteúdo
dinâmico em uma string que será localizada.
Geralmente, isso é feito com outro tipo
de token para representar o conteúdo dinâmico.
Segue-se um exemplo em Java:
HELLO_KEY=Olá {0}!
Na
interface de usuário do aplicativo, não
só “HELLO_KEY” será substituído
por “Olá {0}!”, mas o token “{0}” poderá
ser substituído dinamicamente por qualquer
valor que o aplicativo forneça. Essa substituição
de token é extremamente útil quando
se lida com idiomas que têm outra ordem
de sujeito-verbo-objeto. Em Java, existe suporte
a bibliotecas para essa funcionalidade. Você
pode obter mais informações em http://java.sun.com/.../MessageFormat.html.
Arquivos
específicos a localidades funcionam bem
quando o texto é raramente alterado. No
entanto, no aplicativo de cotações,
havia uma quantidade significativa de texto dinâmico
— principalmente dados de produto. Embora a maioria
dos bancos de dados modernos aceite armazenar
dados UTF, os desenvolvedores precisam ter certeza
de que o banco está configurado corretamente
e de que todas as outras ferramentas usadas para
manipular esses dados também estejam equipadas
para isso. O aplicativo de cotações
foi criado em Oracle, que aceita o conjunto de
caracteres UTF — os desenvolvedores só
precisavam se assegurar de que a variável
de ambiente NLS_LANG estava definida como “american_america.AL32UTF8”.
Também foi preciso que outros aplicativos,
como o SQL*Loader, estivessem configurados corretamente
para lidar com caracteres de byte múltiplo.
Tenha
cuidado ao usar strings UTF como chaves em tabelas
hash ou em bibliotecas de terceiros. Itens que
parecem iguais na tela talvez não sejam
a mesma string de caracteres UTF. Por exemplo,
a combinação de caracteres de acento
pode ou não ser usada para representar
acentos. (Para saber mais a respeito, consulte
as perguntas freqüentes sobre Unicode em
http://unicode.org/faq/char_combmark.html#2)
Em
geral, a formatação de números
e datas é executada pelas bibliotecas de
idiomas (http://java.sun.com/.../DateFormat.html). No aplicativo de cotações,
em vez de usar formatadores de data e número,
foram aproveitados os arquivos específicos
à localidade. Foram acrescentadas duas
chaves, uma para formatação de números
e outra para formatação de datas.
Cada uma delas seria extraída e transmitida
para a classe adequada de formatação
sempre que se exibisse para o usuário uma
data ou um número. Isso significa que todas
as informações específicas
à localidade estavam armazenadas em um
arquivo. Além disso, as bibliotecas Java
não poderiam processar os códigos
do aplicativo para localidades fora do padrão,
o que, como mencionado acima, seria necessário
para fins de compatibilidade.
As
regras comerciais são extremamente específicas
aos aplicativos e são a segunda parte mais
importante da internacionalização
de um aplicativo — a primeira é a exibição
da interface no idioma preferencial do usuário.
Os desenvolvedores devem estar atentos às
regras comerciais relativas às localidades
e criar suporte a elas desde o início.
Por exemplo, no aplicativo de cotações,
usuários em países diferentes teriam
conjuntos diferentes de produtos disponíveis.
Poucas linguagens ou estruturas fornecerão
algum suporte, pois essas regras dependem muito
do aplicativo. Dessa forma, os desenvolvedores
devem planejar a inclusão de conjuntos
de regras personalizadas conforme a localidade
escolhida.
Observe
que isso permite alguns tipos de ataques à
segurança — se os usuários franceses
forem impedidos de comprar determinados itens
permitidos aos japoneses, um francês que
fale japonês poderá escolher a localidade
japonesa e ver os itens proibidos. Como em geral
é solicitado que o usuário escolha
uma localidade, eles podem driblar algumas regras
comerciais que se baseiem nessa escolha. Assim,
às vezes é necessário implementar
processos comerciais para lidar com questões
específicas à localidade. No caso
mencionado acima, as centrais de atendimento que
perceberem uma cotação indevida
poderão escolher ignorá-la ou responder
diretamente ao usuário, informando que
sua localidade não é permitida.
A
classificação correta de texto de
determinada localidade é uma questão
complicada. Mais uma vez, parece haver algum suporte
a bibliotecas (http://java.sun.com/.../Collator.html), mas inicialmente o
aplicativo de cotações não
aceitava classificações específicas
a localidade. No entanto, versões posteriores
exigiram que o aplicativo classificasse texto
localizado. Em vez de usar o suporte a bibliotecas,
foi criada uma interface personalizada para permitir
que os usuários comerciais tivessem a opção
de definir a ordem de classificação
para qualquer coluna em uma tabela. Isso permitiu
que os administradores aplicassem à coluna
uma classificação alfanumérica
padrão, e que os usuários, depois,
pudessem alterá-la.
Uma
vez que todo o texto da interface do usuário
tenha sido substituído por tokens, inclusive
— se for preciso — a formatação
de datas e números, pode-se executar o
aplicativo e testar a interface. A geração
de fato da interface de usuário do aplicativo
é feita quando este sabe a localidade do
usuário, de forma que o idioma, a formatação
de números e outros recursos específicos
à localidade sejam adequados e exibidos
corretamente. Em aplicativos de desktop, isso
pode ser feito na instalação; em
aplicativos Web, a substituição
geralmente é feita em tempo de execução.
Questões
operacionais
A internacionalização é mais
do que simplesmente extrair strings de arquivos
e descobrir a localidade da preferência
de um usuário. Em aplicativos Web, a disponibilidade
pode ser um desafio. Implantar novas versões
do aplicativo de cotações foi um
problema, devido aos variados fusos horários
dos países incluídos. A implantação
do aplicativo afetou severamente sua disponibilidade
durante um curto período pois, quase sempre,
em algum lugar ainda era de tarde no horário
comercial. Embora os desenvolvedores pudessem
visualizar os logs de uso e encontrar um horário
nos dias úteis em que um mínimo
de pessoas estivesse usando o aplicativo, esse
período só servia para implantações
rápidas ou alterações de
configuração. Em qualquer situação
que exigisse mais do que alguns minutos de paralisação,
a solução era implantar na noite
de sexta-feira ou no sábado, que já
é fim de semana em todos os fusos horários.
Mas isso não era muito aceito pelos desenvolvedores
que davam suporte ao aplicativo.
Além
disso, do ponto de vista da modelagem de dados,
os aplicativos internacionalizados podem dar um
pouco de dor de cabeça. Em todas as tabelas
que contenham texto a ser exibido para um usuário,
existirá uma chave para a tabela de localidades.
O aplicativo de cotações ficou com
aproximadamente trinta tabelas com chaves externas
para a tabela de localidades. Uma alternativa
é inserir redundâncias de dados (de-normalize)
nas informações de localidade e
colocar o código real, em vez de uma chave
externa, em todas as tabelas que contiverem texto
exibido para o usuário. Quando essa alternativa
é escolhida, pode-se usar disparadores
para validação e para forçar
a exatidão da localidade. Ambas as soluções
são perfeitamente razoáveis para
atender aos requisitos comerciais e dar suporte
ao aplicativo, mas são difíceis
de administrar e, o que não é tão
importante, um pouco desagradáveis do ponto
de vista dos dados.
Lições
aprendidas
O aplicativo de cotações não
tinha, de imediato, suporte a todos os 27 países
— as localidades foram acrescentadas aos poucos.
Essa abordagem gradual permitiu resolver questões
específicas aos processos, especialmente
o de localização. Ela permitiu também
que a manutenção e administração
do site amadurecessem.
O
uso de códigos de localidade padrão
sempre que possível maximiza a compatibilidade
e pode evitar muita dor de cabeça. No entanto,
talvez existam fortes razões comerciais
proibitivas, e a incompatibilidade poderá
ser contornada.
A
internacionalização deve ser considerada
desde o primeiro momento. Além do tédio
de extrair todas as strings presentes na interface
do usuário, a complexidade do suporte às
regras comerciais recomenda a criação
de algum suporte em todos os aplicativos, desde
o início.
Em
resumo, a internacionalização de
software, seja ele de desktop ou de Web, não
é tão difícil assim. Há
um número definido de questões a
serem tratadas, sendo que a mais longa e tediosa
é a extração, para arquivos
separados, de todas as strings exibidas. Quase
todas as tarefas de internacionalização
ficam mais fáceis se forem levadas em conta
desde o começo do projeto, em vez de serem
deixadas para o final — e, do ponto de vista da
internacionalização, passar de uma
localidade para duas geralmente é mais
difícil do que passar de duas para N localidades.
A maioria das linguagens modernas de programação
tem um amplo suporte a bibliotecas para internacionalização,
que deve ser aproveitado sempre que possível.
¹
Para obter mais informações, verifique
o tópico “How to read, add or modify Windows
registry entries with REGEDIT” (Como ler, acrescentar
ou modificar entradas do Registro do Windows com
o REGEDIT), no site de Rob van der Woude (http://www.robvanderwoude.com/index.html). O artigo pode ser encontrado
se você clicar no link “Batch files” da
seção “Scripting” da home page.
²
Os códigos de idiomas podem ser encontrados
em http://www.loc.gov/.../English_list.php, e os códigos
de países em http://www.iso.org/.../list-en1.html. As bibliotecas Java
usam os códigos ISO nas classes de localidade:
http://java.sun.com/.../Locale.html
Dan
Moore é um consultor independente
que tem trabalhado com tecnologias de Web desde
1997. Ele colaborou com a Zia Consulting na expansão
do aplicativo Web de cotações descrito
acima e familiarizou-se com as “pegadinhas” da
localização e internacionalização
de software. Dan tem escrito artigos e feito apresentações
para grupos técnicos locais sobre temas
que vão da internacionalização
ao uso de Java no celular e à tecnologia
de autenticação Java. Formado em
Física pelo Whitman College, ele mantém
um blo expansão
do aplicativo Web de cotações descrito
acima e familiarizou-se com as “pegadinhas” da
localização e internacionalização
de software. Dan tem escrito artigos e feito apresentações
para grupos técnicos locais sobre temas
que vão da internacionalização
ao uso de Java no celular e à tecnologia
de autenticação Java. Formado em
Física pelo Whitman College, ele mantém
um blog que abrange vários tópicos
técnicos (e umas elucubrações
ocasionais) em http://www.mooreds.com/weblog.