Gestión de una aplicación completa con .NET Servicio de Informática TEMA 6: Internacionalización de aplicaciones Índice de contenido Introducción ....................................................................................................................................1 Identificadores estándar de idioma..................................................................................................2 Leer el idioma del navegador..........................................................................................................2 Acceso a recursos locales y globales..............................................................................................3 Establecer la referencia cultural y la referencia cultural de la interfaz de usuario para la globalización de páginas Web ASP.NET.........................................................................................3 Establecer mediante declaración la referencia cultural y la referencia cultural de la interfaz de usuario de una página Web ASP.NET.........................................................................................4 Establecer mediante programación la referencia cultural y la referencia cultural de la interfaz de usuario de una página Web ASP.NET.........................................................................................4 Acceso a propiedades de la globalizacion.......................................................................................5 La Clase ClaseIdioma.....................................................................................................................6 Incluir la clase..............................................................................................................................6 Especificar un idioma para un objeto...........................................................................................7 Acceso a campos de BD en varios idiomas.................................................................................9 Temas según idioma.......................................................................................................................9 Introducción En el pasado, el término localización se refería a menudo a un proceso que comenzaba después de que un programador de aplicaciones compilase los archivos fuente en el idioma original. Entonces, otro equipo iniciaba el proceso de modificación de los archivos fuente para que pudieran usarse en otro idioma. El idioma original podía ser, por ejemplo, el inglés; y el segundo idioma, el alemán. Este enfoque, sin embargo, es prohibitivo y provoca incoherencias entre versiones. Incluso ha propiciado que algunos clientes se decidieran a comprar la versión original del programa para no tener que esperar la durante varios meses la llegada de la versión localizada. Las principales ventajas de diseñar e implementar aplicaciones que tengan en cuenta y se adapten a las convenciones regionales, a datos en diversos idiomas y a formatos diferentes son: • • • Se puede lanzar la aplicación al mercado más rápidamente. No se necesita desarrollo adicional para localizar una aplicación una vez que la versión original está completa. Se aprovechan los recursos de manera más eficaz. Al convertir la adaptación a criterios internacionales en una parte del proceso de desarrollo original, hacen falta menos desarrollo y menos recursos de comprobación que si agregara esa opción una vez iniciado el trabajo. Es más, si agrega la adaptación a criterios internacionales cuando la aplicación esté concluida, es posible que la haga menos estable, y cree problemas que podría haber resuelto al principio. La aplicación es más fácil de mantener. Si genera la versión localizada de la aplicación desde el mismo conjunto de fuentes que la versión original, sólo algunos módulos aislados necesitarán localización. Por lo tanto, el código será más fácil y barato de mantener si Tema 6 / Página 1 Gestión de una aplicación completa con .NET Servicio de Informática incluye las características de uso internacional. La clave de este aspecto del diseño de software radica en usar archivos de recursos para las versiones localizadas de la aplicación. Identificadores estándar de idioma Existen unos identificadores estándar para designar el idioma y sus diferentes variantes. Se trata de un código de dos caracteres al que le puede seguir un guion y otro código para especificar una variedad especifica del idioma. Por ejemplo el identificador para el español es es, y el del español de Perú es-pe. Siempre que trabajemos con idiomas hay que utilizar los identificadores estándar y no inventarnos unos nosotros. Las herramientas de internacionalización de Visual Studio trabajan con los estos. Para más información visitar http://msdn.microsoft.com/es-es/library/system.globalization.cultureinfo(v=VS.80).aspx Los que nos van a interesar son: es ca en Español Catalán Inglés Leer el idioma del navegador Los usuarios pueden establecer la referencia cultural de la interfaz de usuario y la referencia cultural en sus exploradores. Por ejemplo, en el menú Herramientas de Microsoft Internet Explorer, los usuarios pueden hacer clic en Opciones de Internet y después, en la ficha General, hacer clic en Idioma y establecer su preferencia con respecto al idioma. Si el atributo enableClientBasedCulture del elemento globalization en el archivo Web.config se establece en true, ASP.NET puede establecer automáticamente la referencia cultural de la interfaz de usuario y la referencia cultural para una página Web, a partir de los valores que envía un explorador. No es recomendable confiar exclusivamente de la configuración del explorador para determinar la referencia cultural de la interfaz de usuario de una página. Con frecuencia, los usuarios utilizan exploradores que no están configurados según sus preferencias (por ejemplo, en los cibercafés). Debe proporcionar un método para que los usuarios elijan explícitamente un idioma o un idioma y una referencia cultural (nombre CultureInfo) para la página. Para obtener el idioma que tiene configurado el cliente en su navegador utilizaremos la matriz UserLanguages del objeto Request. Matriz String que contiene los idiomas especificados en el encabezado AcceptLanguage de la solicitud o bien null, si la solicitud de cliente no incluía un encabezado AcceptLanguage Ejemplo: Si queremos ver todos los idiomas del cliente Tema 6 / Página 2 Gestión de una aplicación completa con .NET Servicio de Informática // Muestra las preferéncias de lenguaje. string[] types = Request.UserLanguages; if (types != null) { Label1.Text = "<br />Lenguajes aceptados:"; foreach (string s in types) { Label1.Text = String.Concat("<br/>",s)); } } Acceso a recursos locales y globales Para acceder a recursos locales se utiliza el método GetLocalResourceObject que recibe como argumento el nombre del recurso al que queremos acceder. protected void Page_Load(object sender, EventArgs e) { Label1.Text = GetLocalResourceObject("mensajeBienvenida"); } Con los recursos globales será muy parecido a los anteriores pero especificando el fichero global al que queremos acceder. Tendremos dos formas de hacerlo. Mediante el método GetGlobalResourceObject o con la colección Resources. Por ejemplo si queremos acceder a un recurso llamado tituloGeneral del fichero de recursos elementosComunes haremos: GetGlobalResourceObject("elementosComunes","tituloGeneral") o Resources.elementosComunes.tituloGeneral Establecer la referencia cultural y la referencia cultural de la interfaz de usuario para la globalización de páginas Web ASP.NET En una página Web ASP.NET puede establecer dos valores de referencia cultural, correspondientes a las propiedades Culture y UICulture. El valor Culture determina los resultados de las funciones que dependen de la referencia cultural, como el formato de fecha, número y moneda, entre otras. El valor UICulture determina qué recursos se cargan para la página No es necesario que las dos configuraciones de referencia cultural tengan el mismo valor. En función de la aplicación, quizá sea importante establecerlas por separado. Un ejemplo es un sitio de subastas Web. La propiedad UICulture podría cambiar para cada explorador Web, mientras Tema 6 / Página 3 Gestión de una aplicación completa con .NET Servicio de Informática que Culture se mantiene constante. Por consiguiente, los precios siempre se muestran en la misma moneda y formato. El valor Culture sólo se puede establecer con referencias culturales concretas, como en-US o enGB. Esto evita que sea necesario identificar el símbolo de moneda correcto para en, donde enUS y en-GB tienen símbolos de moneda diferentes. Establecer mediante declaración la referencia cultural y la referencia cultural de la interfaz de usuario de una página Web ASP.NET Para establecer la referencia cultural de la interfaz de usuario y la referencia cultural de todas las páginas, agregue una sección globalization al archivo Web.config y, a continuación, establezca los atributos uiculture y culture, tal como se muestra en el siguiente ejemplo: <globalization uiculture="es" culture="es-MX" /> Para establecer la referencia cultural de la interfaz de usuario y la referencia cultural de una sola página, establezca los atributos Culture y UICulture de la directiva @ Page, tal como se muestra en el ejemplo siguiente: <%@ Page UICulture="es" Culture="es-MX" %> Para que ASP.NET establezca la referencia cultural de la interfaz de usuario y la referencia cultural con el primer idioma especificado en la configuración actual del explorador, establezca UICulture y Culture como auto. También puede establecer este valor como auto:culture_info_name, donde culture_info_name es un nombre de referencia cultural. Para obtener una lista de los nombres de referencias culturales, vea CultureInfo. Puede realizar esta configuración en la directiva @ Page o en el archivo Web.config. Establecer mediante programación la referencia cultural y la referencia cultural de la interfaz de usuario de una página Web ASP.NET El método InitializeCulture se ejecuta antes que evento de página, incluso antes que Page_PreInit. Por esta razón no podremos hacer referencia en ella a ningún elemento de la página. Por consiguiente, para leer valores que se pasan a la página desde los controles, debe obtenerlos directamente de la solicitud mediante la colección Form Se utiliza para especificar el idioma que queremos para nuestra aplicación. En concreto para inicializar la información de Culture y UICulture de la página, referentes al identificador de referencia cultural de la página y el id. de interfaz de usuario. Ambos para el objeto Thread asociado a la página. En la práctica le asignaremos valores a estas propiedades de la siguiente forma: Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("ca"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("ca"); Tema 6 / Página 4 Gestión de una aplicación completa con .NET Servicio de Informática Siendo “ca” el identificador de idioma. Finalmente llamamos al método InitializeCulture de la clase base para establecer Culture y UICulture para el subproceso actual de la página. Habrá que incluir dos librerías para que esto funcione: using System.Globalization; using System.Threading; Resumiendo: protected override void InitializeCulture() { Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("ca"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("ca"); base.InitializeCulture(); } Acceso a propiedades de la globalizacion Una vez establecida la información de idioma, podemos acceder a toda la información a través de las clases de derivan de System.Globalizacion.CultureInfo. En concreto de: System.Globalization.CultureInfo.CurrentCulture System.Globalization.CultureInfo.CurrentUICulture Unos ejemplos. • Nombre del idioma en el que se está visualizando la aplicación: System.Globalization.CultureInfo.CurrentCulture.Name System.Globalization.CultureInfo.CurrentCulture.NativeName • Identificador numerico del idioma System.Globalization.CultureInfo.CurrentCulture.LCID • Identificador ISO del idioma (muy importante) System.Globalization.CultureInfo.CurrentCulture.TwoLetterISOLanguageName • Separador decimal del idioma System.Globalization.CultureInfo.CurrentCulture. NumberFormat.CurrencyDecimalSeparator Tema 6 / Página 5 Gestión de una aplicación completa con .NET Servicio de Informática La Clase ClaseIdioma Esta clase estática nos va a servir para trabajar con varios idiomas en las cadenas de información de una clase. Por ejemplo cuando leamos de base de datos un nombre en bilingüe almacenado en dos campos diferentes de una tabla. Incluir la clase Primero debemos hacer una referencia a la DLL. Sobre la carpeta Bin, botón derecho, Agregar referencia … Ilustración 1: Agregar referéncia Debemos pulsar Examinar y acceder a la carpeta /toolsnet/DLLs/ y seleccionar ClaseIdioma.dll Tema 6 / Página 6 Gestión de una aplicación completa con .NET Servicio de Informática Ilustración 2: Agregar Dll Ahora debemos hacer referencia desde nuestro ASPX al espacio de nombres en el que se encuentra nuestra clase ("ua"). using ua; La ClaseIdioma es una clase completamente estática, por lo que no tiene sentido instanciarla. Especificar un idioma para un objeto Internamente el idioma es un identificador entero que nos sirve para acceder a las posiciones de un vector donde se almacenan la información según el idioma. Para obtener este identificador utilizamos el método ConvierteIdioma, acepta los descriptores de Campus Virtual (V,C,I), los descriptores estandar ("ca", "es", "en") y los literales definidos para la enumeración ("Valenciano", "Espanyol", "Ingles") Por ejemplo en una clase me creo una variable miembro para identificar el idioma llamada _idioma. Y en el constructor exijo que se especifique el idioma. Tema 6 / Página 7 Gestión de una aplicación completa con .NET Servicio de Informática public class ClasePrueba { private int _idioma; } public ClasePrueba(string elIdioma) { _idioma = ClaseIdioma.ConvierteIdioma(elIdioma); } Ahora queremos una variable del objeto para almacenar la descripción, que puede estar en cualquier idioma. Para crearla haremos: private string[] _descripcion = new string[ClaseIdioma.NumeroIdiomas]; Si queremos introducir valores utilizaremos la propiedad Idioma que tiene tres identificadores Espanyol, Valenciano e Inglés, que nos devuelve el identificador de cada uno de estos idiomas. _descripcion[(int) ClaseIdioma.Idioma.Espanyol] = "Buenos dias"; _descripcion[(int) ClaseIdioma.Idioma.Valenciano] = "Bon dia"; _descripcion[(int) ClaseIdioma.Idioma.Ingles] = "Good Morning"; Para leer el valor, simplemente usamos el identificador de idioma antes creado como indice del vector. _descripcion[_idioma] Toda la clase junta: public class ClasePrueba { private int _idioma; private string[] _descripcion = new string[ClaseIdioma.NumeroIdiomas]; public ClasePrueba(string elIdioma) { _idioma = ClaseIdioma.ConvierteIdioma(elIdioma); _descripcion[(int) ClaseIdioma.Idioma.Espanyol] = "Buenos dias"; _descripcion[(int) ClaseIdioma.Idioma.Valenciano] = "Bon dia"; _descripcion[(int)ClaseIdioma.Idioma.Ingles] = "Good Morning"; } public string Descripcion { get { return (_descripcion[_idioma]); } set { Tema 6 / Página 8 Gestión de una aplicación completa con .NET Servicio de Informática _descripcion[_idioma] = value; } } } Acceso a campos de BD en varios idiomas Para hacer una consulta en campos virtual en tablas que tiene campos dependientes del idioma podemos usar los métodos ObtenExtensionCVText y ObtenExtensionCVNum que reciben como argumento el identificador de idioma y devuelven la extensión de texto que se le concatena al nombre del campo. Por ejemplo, si tenemos dos campos en la tabla localizaciones llamados desc y descval. Podemos hacer la consulta así: "SELECT codloc, descloc" + ClaseIdioma.ObtenExtensionCVText(_idioma) + " descloc FROM cnet_localizaciones "; Con lo que no tendremos que preocuparnos del idioma, ya que en descloc tendremos siempre el actual. Temas según idioma Si temenos por ejemplo un diseño de página repleto de imágenes con textos, necesitaremos tener versiones de las imágenes en los distintos idiomas que soporte nuestra aplicación Para ello nos podemos crear temas diferentes para cada idioma cuyo nombre termine en un punto más el identificador de idioma y podemos asignarlo en Initialize_Culture de forma muy sencilla mediante: base.Theme = "miTema." + idioma; ¡ The end ! Tema 6 / Página 9