miércoles, 19 de enero de 2011

Propagar atributos en tiles

Una vez que estamos configurando nuestra plantilla de tiles mediante xml se nos puede presentar la necesidad de utilizar atributos dentro de una jsp que se está visualizando mediante un <tiles:insertAttribute />. Voy a poner un ejemplo para que se entienda mejor el caso:

En nuestro fichero tiles-def.xml tenemos el siguiente definition:












El main.jsp tiene el siguiente contenido:


<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
....





Hasta aqui nada raro. Pero, ¿Qué pasa si dentro del header queremos utilizar el atributo menu? header.jsp:


<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>

<img src="<%=request.getContextPath()%>/images/logo.png" />



Si ejecutamos esto nos dara una excepción NoSuchAttributeException, quejándose de que no existe el atributo 'menu'. ¿Qué soluciones tenemos?

La primera opción que se me ocurre y seguramente sea la más elegante es reordenar un poco la definición que tenemos dejándola de la siguiente manera:














Y el main.jsp quedaría:


<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
....





Si esta solución no os convence y no podeis separar la definición existente en dos (como me ha ocurrido recientemente) se puede hacer lo siguiente:

Primero, exponer todos los atributos de la definición como atributos de la request dentro del main.jsp:


<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
....








Después modificamos el header para que, en vez de utilizar el <tiles:insertAttribute/>, se use el <jsp:include/>:


<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>

<img src="<%=request.getContextPath()%>/images/logo.png" />



No me gusta nada esto de tener que utilizar el requestScope y jsp:includes directamente y en mi opinión tiene que haber otra forma de hacerlo más
elegante, pero estuve investigando un poco y no encontré nada. Como esto funciona no le dí muchas más vueltas jeje.