ASP.NET - Globalizando seu site.


Desenvolver aplicações para mais de um idioma requer um planejamento cuidadoso com o método que você vai usar para implementar o suporte aos idiomas na sua aplicação.

A plataforma .NET oferece recursos que podem facilitar esta tarefa e este artigo pretende dar uma introdução e visão geral de como você pode usar tudo isto a seu favor.

Vamos supor que você queira desenvolver um site em dois idiomas diferentes : Inglês e Português. Ao dar suporte a mais de um idioma você terá que ter o conteúdo do site traduzido para cada respectivo idioma, e, isso inclui: texto estático, banners, etiquetas , datas , valores monetários , etc.

Para tratar o problema acima existem diversas soluções que podemos adotar dentre elas temos :

1- Você pode desenvolver as páginas para cada idioma separadas e independentes dento assim dois conjuntos distintos de páginas. Pode então hospedá-las em dois diretórios diferentes um para cada língua respectiva. Nem preciso dizer que esta solução dá muito trabalho de manutenção e de sincronização de conteúdo.

2- Outra solução seria a criação de um banco de dados onde o conteúdo para cada língua fosse armazenado em uma tabela diferente. Em tempo de execução bastaria carregar a tabela referente a língua usada e retornar o conteúdo correspondente ao idioma. O problema desta solução é o custo do armazenamento de dados e o código extra exigido para formatação de datas e valores numéricos.

3- A utilização de arquivos de recursos (resource files) seria outra solução. Nela você armazena todo o conteúdo em arquivos de recursos. Um arquivo de recurso é um arquivo não executável que é requisitado pela aplicação e que é distribuído junto com ela. Um arquivo de recurso pode conter : mapa de bits (bitmaps) , icones, cursores , textos , etc.

Não existe a solução perfeita. A solução pode ser perfeitamente plausível para você se o site que você esta desenvolvendo possuir poucas páginas com pouco conteúdo e sem muita exigência de formatação de valores e datas. A adoção de um banco de dados como proposto na solução dois pode atender bem ao seu caso dependendo da situação. Neste artigo eu vou falar sobre a utilização de arquivos de recursos para a criação de sites com mais de uma língua.

Nota: O artigo -   Globalizando a sua aplicação - Usando os arquivos de recursos - trata do mesmo assunto para o VB6.

Para trabalhar com recursos vamos usar as classes do namespace System.Resources mas antes vou falar um pouco como a plataforma .NET define alguns termos muito importantes que você deve saber e que serão usados decorrer desse artigo.

Globalization - é o processo de identificar e separar da aplicação principal todas as partes de sua aplicação que precisam ser diferentes para um respectivo idioma.

Localization - é o processo de criar e configurar sua aplicação para um idioma específico.

Culture - é a combinação do idioma que você fala e a sua localização geográfica. Isso inclui a forma de representar as datas, horas, e valores monetários. Uma cultura é representa da seguinte forma:

en-US - Inglês falado nos EUA
en-GB - Inglês falado na Inglaterra
en-CA - Inglês falado no Canadá
en-AU - Inglês falado na Austrália 

Para trabalhar com a informação da cultura (culture) a plataforma .NET oferece a classe CultureInfo existente no namespace System.Globalization . Uma cultura é definida em uma linha de execução (Thread) de forma que você vai precisar trabalhar com a classe Thread do namespace System.Threading.

Para obter o valor da cultura atual para um usuário usamos a propriedade CultureInfo.CurrentCulture e para definir uma cultura para uma Thread usamos a propriedade Thread.CurrentThread.CurrentCulture.

Abaixo temos um exemplo de um pequeno projeto ASP.NET feito no Web Matrix que exibe a cultura atual e preenche um listbox com todos os valores de culture instalados na minha máquina:

<%@ Page Language="VB" %>
<%@ import Namespace="System.Globalization" %>
<script runat="server">
    Sub Page_Load(Source as Object, E as EventArgs)

         if not Page.IsPostBack then
    
             Dim ciarr() As CultureInfo = CultureInfo.GetCultures(CultureTypes.InstalledWin32Cultures)
             Dim c As System.Globalization.CultureInfo
             Dim ci As CultureInfo
               
             'exibe a cultura atual
             ci = CultureInfo.CurrentCulture
             Label1.Text = ci.Name
    
             'preenche a listbox com as culturas instaladas 
              For Each c In ciarr
                 ListBox1.Items.Add(c.Name & " - " & c.EnglishName)
             Next
             ListBox1.SelectedIndex = 0
          end if
    End Sub
</script>
<html>
<head>
</head>
<body>
    <form runat="server">
        <p>
            <img style="WIDTH: 258px; HEIGHT: 45px" height="32" src="maco1b.gif" width="233" border="0" />
        </p>
        <p>
            Culturas instaladas
            <br />
            <asp:ListBox id="ListBox1" runat="server" Width="238px" Height="214px"></asp:ListBox>
        </p>
        <p>
            Cultura Atual - <asp:Label id="Label1" runat="server">Label</asp:Label>
        </p>
     </form>
</body>
</html>
 

Para definir um valor para uma cultura especifica podemos fazer assim :
Dim ci as CultureInfo
ci=new CultureInfo("en-GB")
Thread.CurrentThread.CurrentCulture = ci
Response.Write(DateTime.Now)

Neste código define a cultura para "en-GB" ; como consequência a exibição da data será no formato dd/MM/yyyy

Para definir um valor de culture para uma página usamos a diretiva @Page

<%@ Page language="c#" Culture="et-EE"%>

Na diretiva acima eu estou definindo a cultura para "et-EE" - Letônia. Incluindo um controle Calendário na página e executando teremos:

A conversão automática feito no controle Calendar para a cultura definida não se aplica a labels e textos e outros valores presentes na página por isto vamos ter que partir para a utilização dos arquivos de recursos.

O artigo :  VB .NET - Datas e números : globalizando sua aplicação.  mostra o assunto para o VB.NET com formulários Windows.

O que são realmente os arquivos de recursos ?

Como já foi dito anteriormente  :  "Um arquivo de recurso é um arquivo não executável que é requisitado pela aplicação e que é distribuído junto com ela. Um arquivo de recurso pode conter : mapa de bits (bitmaps) , icones, cursores , textos , etc."

Para criar um arquivo de recursos temos que criar primeiro um arquivo texto(.txt) ou XML(.xml) contendo a informação do recurso desejado e a seguir compilar o arquivo para gerar o arquivo de recurso correspondente.

Temos então dois tipos de arquivos de recursos onde podemos armazenar o conteúdo da informação que desejamos tratar:

1 - Arquivos Textos :  São arquivos ASCII do tipo texto onde usamos valores pares de chave e informação. Estes arquivos não podem tratar dados binários como imagens ou objetos

Para criar este arquivos usamos qualquer editor de textos como o Bloco de Notas. Usando o VS.NET podemos incluir um arquivo texto a um projeto e então incluir uma chave relacionada com o texto . Ex:abaixo temos o arquivo texto1.txt com a relação chave/valor.

texto1.txt
label1=Olá Pessoal.

2- Arquivos .resx : São arquivos que contém além de texto dados binários. Atualmente são arquivos XML que podem ser tratados no VS.NET.

Para criar arquivos .resx podemos usar o VS.NET. Estando com seu projeto aberto no VS.NET selecione no Menu File a opção - Add New Item - e a seguir selecione na janela - Add New Item - Assembly Resource File - conforme figura abaixo:


Um arquivo .resx também pode conter a informação de conteúdo via relacionamento chave/valor. Exemplo:

<data name="label1">
        <value>Ola Mundo</value>
</data>

Naturalmente cada localização de sua aplicação vai requerer um arquivo de recursos e é bom você seguir algumas regras para dar nome ao arquivo afim de facilitar sua manutenção. Uma sugestão é dar nomes relacionados a cada idioma de localização. Assim :

<nome base do arquivo>.<localização>.txt ou  <nome base do arquivo>.<localização>.resx

Exemplos :

mensagens.en-US.txt ,   mensagens.en-GB.txt ,  mensagens.fr.txt , mensagens.pt-BR.resx

Após criar o arquivo de recurso com seu conteúdo você deve compilar o arquivo. Para isto você pode usar o utilitário ResGen que acompanha a .NET SDK

Exemplo de compilação:  resgen mensagens.fr.txt  ou   resgen  mensagens.pt-BR.resx

Após gerar os arquivos de recursos você esta pronto para usá-los. Vejamos como podemos fazer isto:

Existem duas maneiras de usar os arquivos de recursos:

  1. Você embute os arquivos de recursos em um assembly e então dependendo da localização especifica o assembly do qual os recursos serão extraídos.
  2. Você especifica explicitamente o arquivo de recurso da localização atual na qual você vai extrair os recursos. Exemplo :
Dim x As Resources.ResourceManager

x = ResourceManager.CreateFileBasedResourceManager("arquivo_de_recursos.en-GB", ".",Nothing)

Label1.Text=x.GetString("message")

- Neste código criamos uma variável do tipo ResourceManager. Esta classe esta no namespace System.Resources.
- Chamamos então o método estático(shared) CreateFIleBaseResourceManager que cria uma instância dele.
- Passamos três parâmetros para o método :
         1- O nome do recurso para uma localização definida
         2- O diretório no qual o arquivo de recursos existe
         3-  A definição do recurso que no nosso caso é Nothing. (isto significa que o recurso padrão será usado)        

Em páginas ASP.NET podemos usar arquivos de recursos : controles code-behind compilados podem utilizar arquivos de recursos embutidos ou vinculados aos seus assemblys.

Para criar arquivos de recursos em tempo de programação usamos a classe ResourceWriter ou a ferramenta, já mencionada acima, Resgen.exe.

Ambos criam arquivos de recursos que podem ser usados por sí ou como parte de um assembly. Para incluir um arquivo de recursos em um assembly você usa o compilador relacionado ou a ferramenta A1.exe. Assemblies que contém somente recursos localizados e nenhum código são chamados de satelite.

Usando arquivos de recursos em uma página ASP.NET

A teoria é importante mas vamos por em prática tudo que foi dito acima. Vamos criar uma página em seis idiomas :  Português, Espanhol, Francês, Alemão, Italiano e Inglês.

Vou criar uma página muito simples onde irei exibir um poema de Fernando Pessoa traduzido para cada um dos idiomas citados acima conforme a seleção que o usuário fizer através do controle radiobuttonlist.

Abra o Webmatrix e crie uma nova página ASP.NET conforme indicado na figura abaixo:

A pasta GlobalApp será o diretório virtual da nossa aplicação onde iremos colocar todos os arquivos de recursos , imagens e o arquivo de script ASPX. Para uma aplicação mais complexa é recomendável a criação de uma estrutura de diretórios para facilitar a manutenção da aplicação.

 Na guia Web insira 5 controles Label e um controle RadionButtonList conforme figura abaixo:

Nesta página temos 5 controles Label da classe System.Web.UI.WebControls.Label.

O identificador(ID) de cada controle é:

lblCultura  - exibe a cultura atual selecionada
lbltitulo - exibe o titulo do arquivo de recurso
lblData - exibe a data localizada
lblpoesia - exibe a poesia do arquivo de recurso
lblautor - exibe o autor do arquivo de recurso

Para incluir os idiomas no RadioButtonList selecione Items para abrir a janela - ListItem Collection . Inclua o texto conforme abaixo e deixe a propriedade do idioma Português em Selected como True. Assim quando a página for carregada pela primeira vez este idioma será o selecionado.

Agora basta criar os seis arquivos de recursos , um para cada idioma. Primeiro vamos criar os arquivos textos para cada língua onde vamos definir a chave e o respectivo conteúdo que será carregado na página.

Assim teremos os seguintes arquivos que iremos :

Vejamos o conteúdo de arquivo resource.txt que é o arquivo em português , o arquivo padrão da nossa aplicação .

titulo = "Fernando Pessoa"
poesia =Eu tenho id&eacute;ias e raz&otilde;es ,<br> Conhe&ccedil;o a cor dos argumentos <br>E nunca chego aos cora&ccedil;&otilde;es.
autor = Fernando Pessoa - 1932

Usando o tradutor do AltaVista eu fiz a tradução da poesia para cada um dos idiomas e assim criei cada arquivo de recurso. O arquivo de recurso do idioma Inglês ficou assim:

titulo = Poetries
poesia = I have ideas and reasons,<br> I know the color of the arguments <br> and I never arrive at the hearts.
autor = Fernando Pessoa - 1932

Note que eu utilizei caracteres de formatação HTML para que o texto fosse exibido na página de forma mais correta.

Agora vamos usar a ferramenta Resgen.exe do VS.NET para compilar os arquivos textos e gerar os arquivos de recursos. Vamos então para o prompt do DOS ; Clique no botão Iniciar do Windows ; a seguir clique em Todos os Programas ; Selecione na sequência : Microsoft Visual Studio .NET 2003 > Visual Studio .NET Tools > Visual Studio .NET 2003 CommandPrompt , conforme figura abaixo:

Agora posicione na pasta da nossa aplicação  : d:\inetpub\wwwroot\GlobalApp (no seu caso pode ser outra caminho) e digite o comando para compilar cada arquivo de recurso conforme figura abaixo:

Pronto , você deverá ter no seu diretório os arquivos de recursos conforme mostrado a seguir. Os arquivos de recursos foram colocados em uma pasta chamada recursos subordinada ao diretório da aplicação.

Agora vamos ao código da aplicação contida no arquivo GlobalApp.aspx:

O código HTML do arquivo é gerado pelo WebMatrix e é o seguinte :

<html>
<head id="Head1" runat="server">
    <title>Globalizando sua aplicação ASP.NET</title>
</head>
<body>
    <form id="Form1" runat="server">
        <asp:Label id="lblCultura" runat="server"></asp:Label>
        <br />
        <br />
        <asp:radiobuttonlist id="Radiobuttonlist1" runat="server" borderstyle="Ridge" autopostback="true" _
repeatdirection="Horizontal" repeatlayout="Table">
            <asp:ListItem Value="pt-BR" Selected="True">Portugu&#234;s</asp:ListItem>
            <asp:ListItem Value="es-ES">Espanhol</asp:ListItem>
            <asp:ListItem Value="it-IT">Italiano</asp:ListItem>
            <asp:ListItem Value="fr-FR">Franc&#234;s</asp:ListItem>
            <asp:ListItem Value="en-US">Ingl&#234;s</asp:ListItem>
            <asp:ListItem Value="de-DE">Alem&#227;o</asp:ListItem>
        </asp:radiobuttonlist>
        <p>
            <asp:Image id="Image1" runat="server" ImageUrl="pessoa.gif" Height="181px" Width="130px"></asp:Image>
        </p>
        <p>
            <br />
            <asp:Label id="lbltitulo" runat="server"></asp:Label>
            <br />
            <asp:Label id="lblData" runat="server"></asp:Label>
            <br />
            <br />
            <br />
            <asp:Label id="lblpoesia" runat="server"></asp:Label>&nbsp;<br />
            <br />
            <asp:Label id="lblautor" runat="server">lblautor</asp:Label>
            <br />
            <br />
        </p>
    </form>
</body>
</html>

 

Neste código a única coisa que eu quero destacar é que a propriedade autopostback esta setada como true ( autopostback="true" ) com isto cada seleção feita irá carregar a página.

O código de script foi gerado em C# e é exibido a seguir :

<%@ Page Language="C#" Debug="false" Trace="false" EnableViewState="false" %>
<%@ import Namespace="System.Globalization" %>
<%@ import Namespace="System.Threading" %>
<%@ import Namespace="System.Resources" %>
<%@ import Namespace="System.IO" %>

<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        CultureInfo ci;

        ci = new CultureInfo(Radiobuttonlist1.SelectedValue.ToString());

        Thread.CurrentThread.CurrentCulture = ci;
        Thread.CurrentThread.CurrentUICulture = ci;

          ResourceManager rm = ResourceManager.CreateFileBasedResourceManager("resource", Server.MapPath("recursos") _ 
+ Path.DirectorySeparatorChar, null);

        lbltitulo.Text = rm.GetString("titulo");
        lblpoesia.Text = rm.GetString("poesia");
        lblData.Text = DateTime.Now.ToString("D");
        lblCultura.Text = "Usando a cultura : " + ci.EnglishName;
     lblautor.Text = rm.GetString("autor");
    }
</script>

No código acima eu estou extraindo os dados de cada arquivo de recurso que foram colocados em uma sub-pasta chamada recursos e atribuindo a cada Label da página. Executando o arquivo globalApp.aspx   e selecionando o idioma Inglês teremos:

Isto é apenas uma introdução ao vasto assunto sobre globalização de aplicações na WEB. Para aplicações mais robusta a utilização dos satélites é recomendada , mas isto é assunto para outro artigo...

Até o próximo artigo...

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Referências:


José Carlos Macoratti