gracias (cc) Foto por woodleywonderworks

Aprovechando la reciente traducción de este sitio web al inglés, voy a dedicar este post a explicar cómo gestionar la traducción de contenidos en ASP.NET MVC multi idioma, cuando hablamos de contenido con cierto tamaño y formato, es decir, más allá de los archivos de recursos, útiles sobre todo para palabras o frases cortas.

Traducción mediante archivos de recursos

En mi caso, al iniciar la traducción, empecé utilizando archivos de Recursos (.resx), que permiten disponer de una librería de recursos organizados por clave-valor, en este caso, cadenas, donde es el propio servidor el que gestiona qué idioma mostrar.

Para ello, se dispone de un archivo “Content.resx” donde se definen todos los textos que vamos a utilizar, con su clave correspondiente:

resources1

A continuación, creamos un archivo con el mismo nombre, pero añadiéndole el sufijo del código ISO del idioma al que queremos traducir, que en el caso del inglés es “en”. Por tanto, el archivo será “Content.en.resx”, y duplicamos las claves del archivo original, pero traduciendo el contenido en este caso:

resources2

La aplicación utiliza los valores de:

para determinar el idioma a utilizar, y para ello utilizará el sufijo que hemos añadido al archivo de recursos. En caso de no encontrar ningún archivo con el sufijo correcto (“de”, por ejemplo), utilizará el archivo sin sufijo como fallback. Por eso este archivo sin sufijo siempre representa el idioma por defecto de nuestro contenido.

Las ventajas de este sistema es que al estar los recursos dentro del ensamblado, el acceso a los mismos es inmediato y es el sistema el que se encarga de decidir qué archivo de recursos utilizar en función del idioma, liberándonos de dicha tarea.

En nuestro ejemplo, ya podemos utilizar en la vista el siguiente código (si Content.resx está en el raíz de la aplicación):

que mostrará el subtítulo “Formación académica” en la tercera pestaña de la página “/es/about“, mientras que mostrará “Academic” en la página “/en/about“. En este caso, utilizo un parámetro en cada ruta “{culture}/about” que indica el idioma a seleccionar.

El código de ejemplo que gestiona el cambio de idioma sería:

Que implica que hemos definido en nuestra tabla de rutas que éstas tienen un parámetro {culture} en cada una de ellas. La gestión de rutas multi idioma la dejaremos para otra publicación.

Pero utilizar archivos de recursos tiene dos problemas fundamentales:

  • Al ser archivos compilados, es necesario volver a compilar y publicar las DLLs del site para cualquier modificación, lo que le resta versatilidad y mantenimiento.
  • Cuando necesitamos traducir grandes bloques de contenido, que a su vez incorporan formato HTML, se convierte en un formato poco manejable y que mezcla formato con contenido. Como ejemplo, si accedemos a una página con descripción de proyecto, como /es/Projects/web-personal, observamos que las secciones de “Descripción del proyecto” o “Responsabilidades y tareas” contienen gran cantidad de texto y formato.

Markdown al rescate

Para solucionarlo he separado el contenido en archivos de Markdown para editar el contenido. La sintaxis de Markdown es muy sencilla, y se hizo muy popular para la edición de Wikis, por ejemplo. Existen diversos editores para modificar archivos markdown, si no queremos tener que aprender la sintaxis. Yo estoy utilizando Markdown Pad 2.

Para diferenciar los idiomas, sigo utilizando la misma filosofía de sufijos ISO que con los archivos de recursos, añadiendo “.en” a los archivos en inglés. De esta manera, por ejemplo, para traducir el contenido de la sección “Responsabilidades y tareas” del ejemplo anterior, /es/Projects/web-personal, tenemos 2 archivos: Project12-tasks.md y Project12-tasks.en.md. De esta manera, la gestión del contenido se hace con un editor especializado, que me permite modificar el formato de manera sencilla, y los cambios son visibles con tan sólo subir el archivo afectado, sin tener que recompilar el site.

La edición de un archivo de markup es tan sencilla como abrir el archivo con el editor y realizar las modificaciones al contenido:

project12_tasks

Como se puede observar, el propio archivo de markdown permite incluir códigos HTML, aunque luego no los muestre en la vista previa. Esto es importante porque nos permite total flexibilidad con nuestro contenido y luego veremos como este código HTML insertado sí que es tenido en cuenta a la hora de generar el HTML asociado.

A modo de ejemplo, así es como ha quedado organizado el contenido asociado con el proyecto 12 completo, /es/Projects/web-personal:

project_md

Donde observamos un archivo de recursos para los textos sencillos, y dos archivos de markdown para las dos secciones complejas, y en cada caso, la correspondiente réplica en inglés.

De markdown a HTML

Obviamante, el formato markdown no se puede mostrar directamente en el navegador como tal, sino que tenemos que transformarlo al HTML correspondiente y enviarlo a la vista.

Para ello, utilizo la librería de código abierto MarkdowDeep, que nos permite transformar el contenido markdown en HTML con muy poco esfuerzo. También implementa una librería de cliente que nos permitiría editar el markdown desde el navegador, mediante javascript.

Para instalar la librería, utilizaremos Nuget. Existen dos versiones de la librería: una que sólo incluye la parte de .NET y otra que incluye además el código de cliente. En mi caso, sólo he necesitado la versión de .NET, por lo que procedemos a su instalación, desde la Consola de Nuget:

O a través del gestor de paquetes de Nuget:

markdowndeep

Una vez instalada, la manera más sencilla de utilizar es creándonos una extensión de HtmlHelper que gestione esta tarea:

Notas a destacar:

  • La función recibe como parámetro el nombre base del archivo a generar, por ejemplo “/Texts/Projects/Project12/Project12-desc”, y ella ya se encarga de añadirle el sufijo de idioma correspondiente y la extensión “.md”
  • Si no encuentra el archivo con la extensión del idioma seleccionado, utiliza como fallback el archivo por defecto sin idioma.
  • La lectura del archivo se puede almacenar en Caché, si queremos aligerar la carga de proceso, aunque según mis pruebas, y al ser archivos relativamente pequeños, la mejora es muy poca, del orden de 2ms por archivo.
  • Al instanciar la librería de Markdown con la propiedad MarkdownInHtml = true, permite que el HTML incluido en el archivo se incorpore también a la salida.
  • Finalmente, devolvemos el resultado de la generación con Raw() para que el HTML no se interprete como texto, sino como salida tal cual.
  • La línea de código:

obtiene el idioma seleccionado, en mi caso, de la ruta. Esta línea dependerá de la implementación del idioma de cada uno.

Una vez tenemos la extensión implementada, tan sólo nos queda utilizarla en nuestra vista:

Como nota adicional, he tenido problemas si la ruta del archivo no es un literal de texto, sino una cadena dinámica. En este caso, en lugar de utilizar la extensión, he tenido que utilizar directamente la clase estática para acceder al método:

Conclusiones

La combinación de archivos de recursos para textos cortos y sencillos, con archivos de texto para contenido más elaborados y con formato (en este caso mediante Markdown) nos permiten realizar una gestión sencilla de aplicaciones multi idioma, fácilmente ampliables a nuevos idiomas en un futuro y que facilitan la actualización de los contenidos en un futuro.

Seguramente hay otras soluciones y cada uno tiene sus trucos, pero esta es la que he utilizado yo en mi propia web. ¿Y tú, cómo gestionas grandes bloques de contenido multi idioma? ¡Se aceptan sugerencias!

dominio personalizado (cc) Foto por mistergwilson

En el anterior post sobre la instalación de WordPress en Windows Azure, veíamos como la URL que se generaba para nuestro sitio web era del estilo http://<mi-nombre>.azurewebsites.net. En este artículo vamos a ver cómo modificar la URL para que la web responda a un dominio personalizado propio como http://www.mi-nombre.com, por ejemplo.

Aclaración previa

Antes que nada, hay que hacer una aclaración sobre el funcionamiento de un sitio web en Azure:

Los sitios web gratuitos no permiten la personalización del nombre del dominio

En Azure existen 3 tipos de sitios web:

  1. Gratuito: con pocos recursos, ideal para hacer las pruebas de nuestra página sin coste, dispone de cuotas de uso que bloquean el acceso a la página si se superan..
  2. Compartido: recursos compartidos con otros sitios web, igualmente utiliza cuotas de uso, algo mayores que el modo Gratuito.
  3. Estándar: máquina virtual dedicada donde alojar tantos sitios web como queramos, o soporte el tamaño de la instancia.

Tan sólo los sitios web en modo Compartido o Estándar permiten la personalización del dominio.

Por ello, lo primero que tenemos que hacer es cambiar la web a uno de estos dos modos antes de configurar los dominios. Mi recomendación es hacerlo justo antes de lanzar la web al público final, o si el dominio real ya es necesario tenerlo para usarlo con otros servicios. De esta manera, ahorraremos costes hasta el momento del lanzamiento.

Para ello, accedemos al portal de gestión y entramos en la ficha del site que vamos a modificar. En este caso, he seleccionado el modo Compartido, más económico.

Azure-Shared

Configurando las DNS del dominio

Lo primero que necesitamos es configurar las DNS de nuestro dominio personalizado para que apunten a nuestro website en Azure. Para ello, tenemos que acceder al panel de administración de nuestro proveedor donde registramos el dominio y añadir el siguiente registro CNAME (o alias):

CNAME: <dominio-personalizado> -> http://<mi-nombre>.azurewebsites.net

En mi caso, y siguiendo con el ejemplo anterior, he creado un registro CNAME para mi-nuevo-wordpress.sergigisbert.com que apunta a mi-nuevo-wordpress.azurewebsites.net.

Dominio personalizado

Configurando el site con el nuevo dominio

Una vez tenemos redirigido el dominio y hemos cambiado el modo de proceso del site, accedemos al panel de administración y comprobamos cómo se ha habilitado la funcionalidad de “Administrar dominio”, que en el modo gratuito está deshabilitada. El botón se encuentra en la barra inferior:

Azure-AdminDomains

En la ventana que se nos abre, introducimos el dominio personalizar que previamente hemos redirigido con el alias DNS:

Azure-NewDomain

Es imprescindible realizar el paso del registro DNS antes que el alta del dominio, porque Azure realiza una consulta para verificar que el nuevo dominio apunta al dominio original de Azure.

Una vez que se aplican los cambios y, si todo ha ido correctamente, ya podemos acceder al site con el nuevo dominio:

Azure-CustomDomain

Podemos utilizar tanto un dominio de primer nivel (www.mi-dominio.com), como un subdominio (blog.mi-nombre.com). El único requisito es que el dominio resuelva con un alias al dominio original de azurewebsites.net.

Y con estos sencillos pasos, ya tenemos nuestro propio dominio funcionando con nuestra web en Azure.

Wordpress en Windows Azure

Hoy en día, la mayoría de proveedores de hosting ofrecen la instalación de aplicaciones web populares de manera sencilla. En este caso, un pequeño tutorial para realizar una instalación de WordPress en Windows Azure.

Primeros pasos

En primer lugar, necesitamos una suscripción activa de Azure. Si no disponemos de una, podemos crear una versión de evaluación gratuita de un mes, con un crédito de 150€.

De todas las opciones que nos ofrece Azure, vamos a utilizar el servicio de Websites, que nos proporciona un servidor web escalable sin tener que ocuparnos de administrar, configurar o actualizar la máquina o el sistema operativo que tiene por debajo.

Creación de la web

Una vez ya hemos entrado en el panel de administración, localizamos el botón Nuevo, en la parte inferior izquierda de la pantalla:

Azure-New

y seleccionamos las opciones Proceso / Sitio Web / De la galería:

Azure-New-From-Gallery

Se nos abrirá un asistente donde podemos observar que no sólo vamos a poder instalar WordPress, sino que existen muchas otras aplicaciones disponibles. Pero en este caso, localizamos WordPress al final de la lista y pinchamos en la flecha para ir al paso 2:

Azure-Wizard-1

En el siguiente paso, elegimos el nombre y la url que tendrá nuestro blog dentro del dominio de Azure. En este caso, la url del site para la prueba será http://mi-nuevo-wordpress.azurewebsites.net. Los detalles de implementación que se muestran a continuación los podemos obviar en este momento.

Azure-Wizard-2

En el último paso, se procede a la creación de la BD MySQL gratuita que nos proporciona Azure a través de ClearDB, de 20Mb, más que suficiente para realizar la configuración inicial del blog, aunque no tanto como para un sistema estable en producción. Más adelante es recomendable buscar otras opciones de BD más escalables:

Azure-Wizard-3

Finalizamos el asistente y, en unos segundos, nos aparecerá la nueva web en el listado de servicios:

Azure-Created

Configuración de WordPress

Una vez se han instalado correctamente los archivos en el servidor y se ha creado la base de datos, el siguiente paso consiste en entrar al nuevo site y realizar la instalación propia de WordPress. Para ello, abrimos en el navegador la dirección web que hemos configurado en el paso 2, en mi caso, http://mi-nuevo-wordpress.azurewebsites.net:

Wordpress-Install

En esta pantalla, rellenamos los datos de “Título del blog”, “usuario”, “password” y “email” y WordPress se encarga del resto:

Wordpress-Success

Si volvemos a navegar a la url de nuestro nuevo blog, lo veremos en funcionamiento:

Wordpress-Hello-World

Con estos sencillos pasos, ya tenemos una instalación de WordPress disponible en menos de 5 minutos para empezar a trabajar con ella.