Multi-idioma... ¡Usando páginas maestras!

Después de escribir mi primer post de bienvenida, ahora ya me dispongo a entrar en materia, que es lo que realmente os puede interesar. Concretamente quiero empezar por un tema bastante interesante y aún poco resuelto como es la realización de sitios multi-idioma usando páginas maestras.

El orígen

Una de las características más imporantes de ASP.NET es la posibilidad de usar las funcionalidades de Globalización y Localización, o lo que es lo mismo, conocer el idioma con el que está trabajando el usuario para mostrar los literales correctos, así como las fechas y los números en los formatos apropiados. Toda la información relativa a su uso la podéis encontrar en este artículo de MSDN.

El problema

En muchos casos no se tiene en cuenta que la selección del idioma se debe realizar desde una página maestra, y no desde una página básica. Tal y como se muestra en este artículo , en una página básica únicamente se trata de sobrecargar el método InitializeCulture, y establecer el valor de CurrentCulture (formatos númericos y de fechas) y CurrentUICulture (fichero de recursos a utilizar) del thread actual (System.Thread.CurrentThread).

Sin embargo, este método no es aplicable cuando estamos usando páginas maestras, debido a que éstas no pueden sobrecargar el método InitializeCulture (porqué no heredan de System.Web.UI.Page, si no que heredan de System.Web.UI.MasterPage). Algunas personas intentan sobrecargar el método InitializeCulture tal y como se muestran en los ejemplos comentados, pero no les funciona correctamente porqué se ejecuta antes el método InitializeCulture que el método de selección del nuevo idioma en la página maestra (por ejemplo, si tenemos un DropDownList con varios idiomas, el evento a controlar será el SelectedIndexChanged, y allí se guardará el nuevo idioma seleccionado en una cookie o en una variable de sesión, por ejemplo).

La solución

Únicamente se trata de intentar recuperar el valor del idioma seleccionado mediante el propio control, y no con el uso de cookies o variables de sesión. El método es muy similar al usado en las páginas básicas, ya que en todas ellas debermos sobrecargar el método InitializeCulture, pero en lugar de consultar el valor de la cookie o variable de sesión, consultaremos el valor del control directamente. ¿Como? Pues conociendo el nombre del control en el lado del cliente (nombre del control en el fichero HTML generado), y recuperando su valor mediante el acceso a la colección de valores del formulario (Request.Form). Cómo una imágen vale más que mil palabras, allá vamos... (pasos a seguir):

1) Crear una página maestra, donde incluimos, por ejemplo, un dropdownlist para seleccionar distintos idiomas:

 <asp:DropDownList ID="cmbIdiomas" runat="server" Width="199px">
 <asp:ListItem Value="en-GB">English</asp:ListItem>
        <asp:ListItem Value="es-ES">Español</asp:ListItem>
        <asp:ListItem Value="fr-FR">Français</asp:ListItem>
</asp:DropDownList>

2) Creamos una página básica que use la página maestra anterior, y ejecutamos la aplicación. ¿Porqué? Queremos ver qué nombre tendrá el control dropdownlist (cmdIdiomas) en el lado del cliente (HTML). Así que cuando ya está ejecutada la aplicación, visualizamos el código fuente generado y buscamos el nombre del control:

Podemos ver como el nombre que tiene el control es ctl00$cmbIdiomas.

3) Ahora se trata de recuperar el valor que tiene el control en el método InitializeCulture en la página básica, con un código similar a este:

Protected Overrides Sub InitializeCulture()
        If Not Request.Form("ctl00$cmbLanguage") Is Nothing Then
            System.Threading.Thread.CurrentThread.CurrentCulture = New System.Globalization.CultureInfo(Request.Form("ctl00$cmbIdiomas"))
            System.Threading.Thread.CurrentThread.CurrentUICulture = New System.Globalization.CultureInfo(Request.Form("ctl00$cmbIdiomas"))
        End If
End Sub

De esta manera la página se establecerá en el idioma seleccionado en el dropdownlist, y actuará como si el selector de idioma se encontrara en la misma página y no en una página maestra. 

Conclusión

Cuando me enfrenté al problema comentado, me di cuenta de que es ciertamente importante conocer el orden de ejecución de los distintos eventos en una página ASP.NET. Comprendiendo este orden es más fácil encontrar soluciones a los problemas que nos enfrentamos a diario. La documentación relativa a estos eventos, y en definitva, al ciclo de vida de una página ASP.NET se encuentra en este artículo.

Espero que les haya sido de ayuda...

 

Tags: , , , ,

Comments

XArly
XArly Spain
7/22/2009 10:30:48 AM Permalink

Yo tengo una duda. ¿si tengo 20 paginas Content, tengo que poner esta cuncion en las 20? ¿No hay alguna manera de que lo haga La master page antes de cargar la página?

Antonio Gago
Antonio Gago Spain
11/18/2009 11:35:26 PM Permalink

Hola,

En mi blog explico con una función de Visual Basic cómo obtener el contenido de los controles que queremos recuperar con Request.Form y éstos están en una o más páginas maestras.

El enlace es: http://toniogago.wordpress.com/2009/11/18/request-form-con-paginas-maestras-master-pages/

un saludo.

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading