Páginas estáticas multilingues y con plantilla tiles en struts2

Si, es un título un poco largo, pero he tardado un poco en encontrar una solución a este problema y quiero compartirlo para todos aquellos que os encontréis en la misma tesitura.

Primero, un pequeño resumen de la situación:

  • Aplicación java con struts2+tiles+urlrewrite
  • internacionalización mediante i18n con archivos de properties
  • Necesidad de un número no trivial de páginas “estáticas” con textos largos poco susceptibles de entrar como property.

Los problemas:

  1. No queremos tener una entrada en el tiles.xml por cada página estática pero queremos utilizar las plantillas existentes.
  2. No queremos generar una acción nueva por cada página
  3. No queremos tener que hacer una nueva entrada urlrewrite por cada página
  4. Queremos poder generar páginas de error si no encontramos una página en un idioma determinado.
  5. Queremos poder generar el texto completo en cada idioma como una página html, no como properties.

Si todavía no os habéis hecho una idea, no os preocupeis, es algo normal. Esta situación no se da todos los días.

La solución

O mejor dicho, mi solución…

Voy a crear una única acción que se encargue de determinar el jsp a cargar dentro de la plantilla tiles y voy a modificar una plantilla existente para inyectarle esa nueva página. Además, como el título de la página estará en la plantilla, voy a encargarme de generar el texto en el idioma adecuado. Además, voy a crear un prefijo para el urlrewrite que permita que todo esto quede bonito para google…

Paso a paso:

Modificación del urlrewite.xml:

<rule>
    	<from>^/web/(.*)$</from>
    	<to>/Estaticas.action?pagina=$1.jsp</to>
    </rule>

Con esta regla le decimos que siempre que tengamos una url con la forma /web/mipagina llamaremos a la acción Estaticas y le pasaremos como parámetro mipagina.jsp

Modificacion en struts.xml:

<action name="Estaticas" 
           class="com.yoprogramo.web.action.EstaticasAction">
  <result>/estatica.jsp</result>
</action>

Con esa acción lo que hacemos es llamar a EstaticasAction.java (luego lo vemos) y redirigir a estatica.jsp que tiene este contenido (quitando las cabeceras):

<tiles:definition name="estatica.modif" extends="estatica">
  <tiles:putAttribute name="body" value="${pagina}" />
</tiles:definition>
<tiles:insertDefinition name="estatica.modif" />

Lo que estamos indicando es que se modifique la plantilla con nombre estatica, definida en el tiles.xml y que ponga como atributo body el valor que la acción nos ha devuelto en pagina, de esta manera estaremos utilizando la plantilla definida en el tiles.xml, pero pasándose un jsp distinto. Esta forma de utilizar tiles es lo que se denomina “mutable”, para poder utilizarla hay que incluir en el archivo web.xml:

  <context-param>
        <param-name>org.apache.tiles.factory.TilesContainerFactory.MUTABLE</param-name>
        <param-value>true</param-value>
  </context-param>

Ahora que tenemos todo en su sitio, solo tenemos que crear una estructura donde guardar las páginas de cada idioma y poder localizarlas facilmente. Por ejemplo, yo he creado una con esta estructrura:

Arbol de páginas estáticas

Bajo “es” pondré las páginas en español, en “en” las páginas en inglés y en “multi” las páginas multilingues que utilizan el packages.properties para traducir sus claves.

Lo único que nos queda ahora es programar la acción EstaticasAction.java .. Os dejo el código del execute:

		// Eliminamos ruta de lenguaje
		int idx=pagina.lastIndexOf("/");
		String page_name = pagina;
		
		if (idx>0)
			page_name = pagina.substring(idx+1);
		
		idx = page_name.lastIndexOf(".");
		if (idx>0)
			page_name=page_name.substring(0,idx);
		
		//Parte multilingue.
		//Vamos a crear una página para cada idioma, excepto para las
		//que sean muy simples y esas estarán en el directorio /multi
		if (!pagina.contains("/multi")) {
			String lang = getText("locale.language");
			if (lang==null)
				lang="en";
			pagina = "/"+lang+"/"+pagina;
		}
		
		// Ahora comprobamos si existe la página y si no existe redirigimos
		// a una página de error del tipo multi
		String servletContext = 
                     ServletActionContext.getServletContext()
                                                 .getRealPath("/estaticas");
		String filePagina = servletContext+pagina;
		File f = new File (filePagina);
		if (f.exists())
			pagina="/estaticas"+pagina;
		else
			pagina="/estaticas/multi/noexiste.jsp";
		
		// Ahora ponemos el título, que deberá estar como un texto 
		// en package con la forma web.<nombre_pagina>.titulo
		String key = "web."+page_name+".titulo";
		titulo = getText(key);
		
		return SUCCESS;

Una vez todo puesto en su sitio la mecánica para crear páginas estáticas y usarlas en nuestra aplicación es bastante simple:

  1. Crear un jsp con el texto para cada idioma y colocarlos bajo el directorio correcto (p.je. es/mipagina.jsp y en/mipagina.jsp)
  2. Crear una entrada en el package_en.properties y package_es.properties con la clave web.mipagina.titulo indicando el título de la página en cada idioma. (Recordemos que el titulo está en el head de la página y eso suele estar en la plantilla, no en el jsp que estamos modificando).
  3. Ya podemos acceder a /web/mipagina y ver cómo queda dentro de nuestra plantilla.

Igual inicialmente parece mucho trabajo, pero una vez hecho esto podréis hacer tantas páginas estáticas como queráis sin ningún esfuerzo y ligadas a las plantillas del resto de vuestra aplicación.

Mi primera aplicación para iPhone. (Experiencias con Apple)

Algo que tenía pendiente, y que sabía que tarde o temprano tendría que aprender es a programar para iOS, desde que tengo el iPhone no dejo de sorprenderme de las cosas que se pueden hacer con este aparatito. Aprovechando la excusa de hacer un cliente móvil para BiblioEteca me puse manos a la obra y pude comprobar los pros y contras de programar para iOS.

Pero antes de continuar escribiendo nada sobre el particular, me gustaría que pudieseis ver el video que preparé (gracias al iMovie) sobre la aplicación gratuita que ya está en la appstore de apple:

El resultado no es perfecto, pero si que es lo suficientemente llamativo para ser considerada una aplicación adecuada para el móvil. todavía no he terminado su desarrollo y tengo más ideas interesantes para implementar en la aplicación, pero ya me ha permitido programar en la plataforma iOS y subir a la appstore una aplicación y una actualización de la misma. Este post es un resumen de mis experiencias con apple.
Sigue leyendo

Introdución a Enterprise Service Bus

Una de las características de esta época nuestra que estamos viviendo es el advenimiento de nuevas “tecnologías” de integración para, de una manera u otra, poder estandarizar la forma en la que se hacen estas tareas… Sin embargo, cada vez más estoy convencido de que solo es fuego de cobertura para mantenernos estudiando nuevos estándares en lugar de trabajar sobre lo que queremos… Tengo reservado ese tema para otro post, lo que quería contaros en este es el concepto de Enterprise Service Bus, representado por el estándar JBI o por productos como MULE. Recientemente he dado un curso sobre éste aspecto y os dejo a continuación el material utilizado. Espero que os sirva para algo:

Software utilizado para las demos:

Archivos adicionales:

Para más cursos, podeis consultar la página de Digimate, donde estamos empezando a liberarlos.

Probando la ola

Después de mucho suplicar por ello, parece que al final ya tengo mi acceso a google wave.

Todavía no he tenido el tiempo suficiente para evaluar qué es lo que se puede hacer con ella y para qué se podrá utilizar una vez que todo el mundo tenga acceso a esta herramienta. Ciertamente promete hacer cosas más sencillas y otras, por otro lado, convertirlas en un caos total (no hay pantalla suficiente ni para jugar un sudoku a tres).

El caso es que tengo la oportunidad de probar un nuevo plugin para incluir waves dentro de nuestros post, y no puedo perder la oportunidad de hacerlo… Hay va la ola de prueba para el blog…

[wave id="googlewave.com!w+yAovHV97A"]

Si se os ocurren cosas que hacer con la ola en el blog… Dejadme un comentario.

NOTA: todos los que no teneis una cuenta en la ola vereis una página de ¿publicidad? de wave… Estoy viendo a ver si puedo arreglarlo. Aunque lo ideal es que todos tuviesemos acceso a wave.

Integrando Java y Windows

Recientemente hemos tenido que integrar un sistema diseñado exclusivamente para Windows y Visual Basic a una aplicación web desarrollada completamente en Java (con un framework nuestro)… Aunque la teoría del uso de JNI es bastante sencilla hay cosas que no se explican en ningún sitio y que nos hizo perder muchas horas… Os dejo aqui un resumen de cómo hacer las integraciones y cuales son los problemas más importantes que nos podemos encontrar…

El problema: una aplicación desarrollada por terceros en Visual Basic, en la forma de un par de dlls que se deben registrar y que son llamadas como objetos OLE desde las aplicaciones tenía que ser invocada remotamente por una aplicación web en java corriendo en una máquina Linux…
Sigue leyendo