Está en la página 1de 6

****SECCIN: MIDDLEWARE

****TTULO: Programacin de aplicaciones multiidoma en asp.net


****AUTOR: Manuel Crdenas Thorlund
****PROFESIN: Director Tcnico de N-Idea. Nuevas Ideas
****ENTRADILLA: Hoy en da, las distancias ya no importan y los
clientes pueden venir de cualquier parte del mundo. Por ello, ofrecer
los contenidos web y personalizar las aplicaciones al idioma local se
ha convertido en algo fundamental. En este artculo se van a explorar
las facilidades que ofrece ASP.NET a la hora de crear aplicaciones
multiidioma.
****LADILLO: Introduccin
Dada la gran expansin que ha sufrido Internet es comn que las
pginas web sean vistas por personas de todo el mundo. Parte de esas
personas sern capaces de leer el mismo idioma que nosotros pero la
gran mayora no lo sern. Esa gran mayora, desechar rpidamente
nuestro sitio web y cambiar a otro que le sirva los contenidos en su
idioma nativo. En el mundo de las pginas web personales puede que no
sea demasiado importante, pero en el mundo de las aplicaciones web y
los portales de empresa, la capacidad de servir los contenidos en
diferentes idiomas se convierte en un elemento fundamental y
diferenciador. ASP.NET provee de mecanismos muy potentes que nos
permiten dotar a nuestras pginas de la capacidad de cambiar el idioma
de una manera rpida y elegante.
****SUBLADILLO: Conceptos previos
A la hora de trabajar con aplicaciones multiidioma, tenemos que
trabajar con tres conceptos muy importantes: idioma, cultura y
ficheros de recursos:
Idioma: ser la lengua principal utilizada para la traduccin de
contenidos. El idioma se identifica con un cdigo de 2 letras
como por ejemplo, es espaol, en ingls, de alemn, etc.
Cultura: la cultura identifica la forma de mostrar cierta
informacin dependiendo de la zona. No es lo mismo la forma de
presentar las monedas en Inglaterra que en Estados Unidos o el
formato de fechas en Argentina que en Espaa, cada uno tiene una
cultura diferente pero con el idioma comn. La cultura tambin
se identifica con un cdigo de dos dgitos.
Ficheros de recursos: tienen la extensin .resx y es en ellos en
los que se guardan las cadenas de texto en diferentes idiomas
que se utilizan en el sitio web.
Los exploradores le pasan el idioma y la cultura a los servidores en
el formato idioma-cultura. Si por ejemplo se quisiera pasar el idioma
ingls con la referencia cultural de estados unidos, el cdigo a
utilizar sera en-us (en para ingls como idioma principal y us para
la cultura de EEUU). Una vez que el servidor ha recibido dicha
informacin buscar el fichero de recursos correspondiente y utilizar
sus cadenas de texto.
****LADILLO: Crear un sitio multiidioma
Vamos a crear un nuevo sitio web con Visual Studio que va a contener
dos pginas ASPX y una pgina maestra que las contenga (ver figura 1).
Para poder habilitar diferentes idiomas en nuestro proyecto se va a
utilizar la carpeta de ASP.NET App_LocalResources y el evento de
pgina Initialize_Culture. En la carpeta App_LocalResources ser donde
se guardarn los ficheros de recursos (.resx) con las cadenas de texto
en los distintos idiomas. Para que todo funcione correctamente, la
carpeta de recursos debe estar al mismo nivel que la pgina aspx a la
que corresponde. En el evento Initialize_Culture ser donde le
indicaremos a ASP.net cul ser el idioma y la cultura a utilizar.
Por lo tanto, en nuestro proyecto, le aadiremos las carpetas de
recursos en sus ubicaciones correspondientes (ver figura 1).
****SUBLADILLO: Ficheros de recursos

En los ficheros de recursos ser donde se almacenen las cadenas de


texto que se utilizarn en las pginas. Los ficheros se almacenan
dentro de las carpetas App_LocalResources y debe existir, al menos,
uno por cada pgina. La nomenclatura a utilizar en el nombre de los
ficheros es [nombre_pagina].aspx.[idioma].resx. De esta forma ASP.NET,
a la hora de buscar las cadenas sabr en qu fichero debe buscar. Se
debe crear uno genrico, sin extensin para el idioma, de forma que si
no se encuentra ninguno para el idioma seleccionado, se utilice ese.
Dentro de la carpeta App_LocalResources, se pueden guardar los
ficheros de recursos de forma libre, es decir, se tiene libertad para
guardarlos en carpetas, guardarlos todos juntos, o de la forma que se
quiera. A la hora de crear aplicaciones web grandes, se suelen dividir
los ficheros en carpetas con el nombre del idioma al que pertenecen,
aunque funciona igualmente si se guardan juntos (ver figura 1).
Internamente, los ficheros de recursos se componen de una par (nombre,
valor) y un campo para aadir comentarios. El nombre ser el
identificador que se utilizar en las pginas o en el cdigo para
referirse a su valor (ver figura 2).
****SUBLADILLO: Utilizar los recursos en las pginas
En el proyecto se han incluido dos pginas y una pgina maestra que
las contiene. La primera de ellas est compuesta por dos etiquetas,
una caja de texto, un botn y un hyperenlace (ver Listado 1).
****LISTADO: Cdigo de pagina1.aspx
<%@ Page Language="C#" MasterPageFile="~/principal.master" AutoEventWireup="true"
CodeFile="pagina1.aspx.cs" Inherits="pagina1" Title="<%$Resources:lblTituloPantalla
%>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="cphContenedor" Runat="Server">
<asp:Label runat="server" ID="lblPagina1" Text="<%$Resources:lblPagina1
%>"></asp:Label>
<asp:TextBox runat="server" ID="txtNombre" Width="200px"></asp:TextBox>
<asp:Button runat="server" ID="btnNombre" Text="<%$Resources:btnNombre %>"
OnClick="btnNombre_Click" />
<asp:Label runat="server" ID="lblMensaje"></asp:Label>
<br />
<br />
<asp:HyperLink runat="server" ID="lnkIrPagina2" Text="<%$Resources:lnkIrPagina2 %>"
NavigateUrl="~/Carpeta/pagina2.aspx"></asp:HyperLink>
</asp:Content>

Para indicarle a ASP.NET dnde se quiere que vayan las cadenas de los
ficheros de recursos se utiliza la forma <%
$Resources:nombre_del_recurso%>. De esta forma, en tiempo de
ejecucin, esas variables sern sustituidas por el valor
correspondiente del fichero de recursos del idioma en el que se
encuentre. El siguiente paso ser indicarle al motor el idioma que
debe utilizar para las cadenas de texto.
****SUBLADILLO: El evento Initialize_Culture
El evento Initialize_Culture() es el encargado de indicarle al motor
de ASP.NET el idioma y la cultura en la que se deben renderizar las
cadenas de texto. En nuestro ejemplo, en el evento Initialize_Culture
realizamos las siguientes tareas (ver Listado 2):
Comprobamos si se ha recibido el parmetro lan por la lnea
del explorador.
En caso afirmativo, establecemos la cultura del thread actual y
la de presentacin al cdigo que se pasa. Guardamos el cdigo en
una variable de sesin para que se utilice en otras pginas.
En caso negativo, comprobamos si tenemos el idioma en sesin, si
no, utilizamos el espaol e inicializamos las referencias
culturales.
****LISTADO: Inicializar el idioma y la cultura
protected override void InitializeCulture()
{
try
{
string idioma = Request.Params["lan"].ToString();
Thread.CurrentThread.CurrentCulture =

CultureInfo.CreateSpecificCulture(idioma);
Thread.CurrentThread.CurrentUICulture =
new CultureInfo(idioma);
Session.Add("idioma", idioma);
}
catch
{
if (Session["idioma"] == null)
Session.Add("idioma", "es");
string idioma = Session["idioma"].ToString();
Thread.CurrentThread.CurrentCulture =
CultureInfo.CreateSpecificCulture(idioma);
Thread.CurrentThread.CurrentUICulture =
new CultureInfo(idioma);
}
base.InitializeCulture();
}

Este evento se debe incluir en todas las pginas que vayan a utilizar
referencias culturas. Normalmente, este evento se suele codificar en
una pgina padre de la que heredan las hijas, de forma que no se tenga
que repetir en todas.
****SUBLADILLO: Cambio manual del idioma
En la pgina maestra se encuentran los controles para realizar el
cambio manual de idioma (ver Figura 3). Se han incluido tres
hyperlinks con la imagen de las banderas de cada idioma. En el evento
Page_Load() de la pgina maestra se inicializa la propiedad
Navigate_Url() de los enlaces para que apunten a la pgina actual y le
aadan el parmetro lan con la referencia cultural:
****CODIGO:
this.lnkEs.NavigateUrl = this.Page.AppRelativeVirtualPath + "?lan=es";
this.lnkEn.NavigateUrl = this.Page.AppRelativeVirtualPath + "?lan=en";
this.lnkPt.NavigateUrl = this.Page.AppRelativeVirtualPath + "?lan=pt";

De esta forma, dependiendo de la pgina en la que nos encontremos, el


enlace apuntar a la pgina correcta pasndole el idioma. Al hacer el
postback, el evento Initialize_Culture cazar el parmetro lan y
cambiar el idioma de la interfaz.
Al cambiar la referencia cultural, todos los controles de ASP.NET que
contengan palabras, fechas, monedas, etc. aplicarn el cambio y las
mostrarn en el formato correcto. En la pagina2.aspx del proyecto se
ha incluido un elemento Calendar. Inicialmente, utilizando la
referencia por defecto (espaol), el calendario muestra los meses en
espaol y el primer da de la semana es el lunes. Si se cambia el
idioma al ingls o al portugus, el calendario cambia automticamente
su formato y muestra el primer da de la semana el domingo y traduce
los meses (ver Figura 4).
****SUBLADILLO: Utilizacin de recursos desde cdigo
Como no todas las cadenas son estticas, debemos ser capaces de
referenciar los recursos desde cdigo para utilizarlos a nuestro
antojo. En la pagina1.aspx del proyecto se ha incluido una caja de
texto con un botn. Al pulsar el botn se lanza un evento en el que se
comprueba si la longitud del texto introducido es o no menor de 5
letras (ver Figura 5). En caso afirmativo se muestra un texto en
pantalla y en caso contrario se muestra otro. Estos textos dinmicos
se definirn igualmente en los ficheros de recursos y se referenciarn
desde cdigo utilizando la instruccin GetLocalResourceObject:
****CODIGO:
int longitud = this.txtNombre.Text.Length;
if (longitud < 5)
this.lblMensaje.Text =
this.GetLocalResourceObject("lblMenosLetras").ToString();
else

this.lblMensaje.Text =
this.GetLocalResourceObject("lblMasLetras").ToString();

De esta forma, el motor de ASP.NET decidir en base al idioma, con qu


cadena sustituye ese valor.
****LADILLO: Deteccin automtica del idioma
Ya tenemos un proyecto con el multiidioma habilitado. Sin embargo, el
cambio lo debe hacer manualmente el usuario. Al acceder a una de las
pginas por primera vez, el motor de ASP.NET coge las cadenas de los
ficheros de recursos sin extensin de idioma, en nuestro caso el
espaol. Para sitios web pblicos, pginas de empresa, catlogos, etc.
es ms interesante que se muestren los contenidos directamente en el
idioma del usuario. Para ello debemos capturar el idioma del
explorador y cambiar la referencia cultural a dicho idioma
automticamente.
Para detectar automticamente el idioma del navegador tendremos que
variar el cdigo evento Initialize_Culture (ver Listado 3).
****LISTADO: Deteccin automtica desde el navegador
protected override void InitializeCulture()
{
try
{
string idioma = Request.Params["lan"].ToString();
Thread.CurrentThread.CurrentCulture =
CultureInfo.CreateSpecificCulture(idioma);
Thread.CurrentThread.CurrentUICulture =
new CultureInfo(idioma);
Session.Add("idioma", idioma);
}
catch
{
if (Session["idioma"] == null)
{
// Obtener el idioma del navegador
string refCultural = Request.ServerVariables["HTTP_ACCEPT_LANGUAGE"];
if (refCultural.Length > 5)
refCultural = refCultural.Substring(0, 5);
Session.Add("idioma", refCultural);
}
string idioma = Session["idioma"].ToString();
Thread.CurrentThread.CurrentCulture =
CultureInfo.CreateSpecificCulture(idioma);
Thread.CurrentThread.CurrentUICulture =
new CultureInfo(idioma);
}
base.InitializeCulture();
}

En este caso, si no se recibe ningn parmetro desde la lnea del


explorador y la variable de sesin del idioma es nula, obtendremos el
valor de la variable de servidor HTTP_ACCEPT_LANGUAGE. Esta variable
contiene el idioma y la cultura del explorador. Por ejemplo, si
cambiamos el idioma del navegador a portugus, en esta variable se
enviar el valor pt-pt. Ahora bien, en el proyecto no hemos definido
el idioma pt-pt, por lo que qu idioma se mostrar? La respuesta es
que se mostrar el idioma portugus porque ASP.NET se quedar con el
idioma y obviar la referencia cultural, salvo en los controles tipo
Calendar. Si el explorador enviara la referencia pt-br, indicando
portugus brasileo, se mostrara igualmente el idioma portugus.
Qu pasa si el idioma no est soportado por nuestra aplicacin? Si se
recibe un idioma para el que no se han creado recursos especficos,
ASP.NET cambiar automticamente al idioma por defecto. Si se quiere
personalizar las cadenas de texto para diferentes culturas dentro de
un idioma se pueden crear ficheros de recursos cuya extensin sea
idioma-cultura. Por ejemplo, si se quiere distinguir entre espaol con

referencia argentina y el resto de espaol, se crear un fichero con


el formato [nombre_de_pagina].aspx.es.resx y otro
[nombre_de_pagina].aspx.es-AR.resx. Si se recibe una peticin de un
navegador con idioma espaol y cualquier cultura menos la argentina se
utilizarn las cadenas del primer fichero. En cambio, si se recibe una
peticin con cultura argentina, se utilizarn las cadenas del segundo
fichero.
****LADILLO: Mensajes de capa de negocio
Hasta ahora se han tratado las cadenas y mensajes directamente en las
pginas web, utilizando la carpeta App_LocalResources. Sin embargo, en
una aplicacin web normal tendremos una capa de negocio (en un
proyecto aparte) que se encargar de ejecutar la mayora de las
acciones y que devolver mensajes de xito o error a la capa de
presentacin. Dichos mensajes deben de estar tambin personalizados
para cada idioma pero nos encontramos con dos problemas:
No se pueden referenciar ficheros de recursos desde otros
proyectos.
Las clases se utilizan en muchas pginas por lo que no podemos
incluir dichos mensajes en el fichero de una pgina porque no
podramos utilizarlo en otra distinta.
Para solventar el segundo problema ASP.NET provee de una carpeta
llamada App_GlobalResources donde podremos crear recursos disponibles
para todas las pginas del proyecto web. Para arreglar el primer
problema, utilizaremos la expresin GetGlobalResourceObject en el
cdigo.
En el proyecto se ha creado una nueva clase (simulando un proyecto de
negocio) dentro de la carpeta App_Code y se han incluido tres nuevos
ficheros de recursos dentro la carpeta App_GlobalResources para los
idiomas de la aplicacin (ver Figura 6). Los ficheros de recursos
dentro de la carpeta Global no tienen que seguir la nomenclatura que
los de las pginas, salvo en la extensin de idioma. Lo que se va a
hacer es pasar el cdigo del botn de la pagina1.aspx a la clase de
negocio de forma que el mensaje que se muestra en pantalla sea
generado por la clase y no por la pgina. Para ello se deben hacer
pequeos cambios en el proyecto:
Mover los recursos lblMasLetras y lblMenosLetras de los
ficheros de recursos locales a los ficheros globales.
Crear la clase de Negocio.cs (ver Listado 4)
Cambiar el cdigo del botn (ver Listado 5)
****LISTADO: Clase negocio.cs
public class Negocio
{
public Negocio()
{
}
public string MetodoDePrueba(string texto)
{
int longitud = texto.Length;
if (longitud < 5)
return "lblMenosLetras";
else
return "lblMasLetras";
}
}

****LISTADO: Cdigo del botn


protected void btnNombre_Click(object sender, EventArgs e)
{
// Llamamos al metodo de negocio
Negocio objNegocio = new Negocio();
this.lblMensaje.Text =
this.GetGlobalResourceObject("Errores",
objNegocio.MetodoDePrueba(this.txtNombre.Text)).ToString();
}

Al pulsar el botn de la pantalla, se realiza una llamada al mtodo


MetodoDePrueba de la clase Negocio. Dicho mtodo evala la longitud de

la cadena pasada y devuelve el nombre del recurso a utilizar. Para


indicarle a ASP.NET dnde se encuentra el recurso devuelto por la
clase, en el botn utilizaremos la funcin GetGlobalResourceObject.
Esta funcin toma como argumentos el nombre del fichero donde se
encuentra la cadena y el nombre de la cadena, devolviendo el valor de
la misma.
De esta forma, se pueden utilizar mensajes globales desde clases que
se encuentren en distintos proyectos, referencindolas desde cualquier
pgina y manteniendo el multiidioma.
****LADILLO: Conclusiones
En este artculo se han explorado las opciones que ofrece ASP.NET para
la creacin de aplicaciones web multiidioma. El resultado es un
desarrollo elegante y sostenible al crecimiento de los sitios. Sin
embargo, como en todas las tecnologas, hay que evaluar los pros y
contras. Antes de embarcarse en un desarrollo sobre varios idiomas hay
que tener en cuenta que exige ms esfuerzo, al tener que tener
archivos de recursos para cada una de las pginas y cada uno de los
mensajes de la capa de negocio o datos. Tambin hay que ser
extremadamente cuidadoso a la hora de crear los valores en los
ficheros de recursos porque todos los valores deben existir en todos
los ficheros. En caso que en algn idioma falte algn valor, al
acceder a dicha pgina se generar un error en tiempo de ejecucin.
Por el contrario, los ficheros de recursos son, al final, documentos
XML, lo que permite su automatizacin desde aplicaciones externas de
una forma muy fcil. Esto ofrece una gran flexibilidad a la hora de
realizar las traducciones, pudindose crear aplicaciones especficas
de traduccin que lean y manejen dichos documentos XML.
****figura1.tif: Estructura del proyecto.
****figura2.tif: Fichero de recursos (pagina1.aspx.resx) de la
pgina1.aspx en el idioma por defecto.
****figura3.tif: Pgina1.aspx en el idioma espaol con los controles
de cambio de idioma.
****figura4.tif: Pgina2.aspx en portugus. El calendario cambia
automticamente la cultura y muestra el domingo como primer da.
****figura5.tif: Utilizacin dinmica de los recursos en la pgina.
****figura6.tif: Nueva clase de negocio.

También podría gustarte