Abr 30 2009

Apache Tiles, un sistema de plantillas

Categoría: DAD,InformáticaMiguel Angel @ 0:55

apachetiles

NOTA: esta entrada es para la versión 2.1 de Apache Tiles.

En una entrada anterior estuvimos hablando de cómo crear una librería de etiquetas JSP. En la presente vamos a utilizar una que nos permita crear un sistema de plantillas.

¿Pantillas? Sí, plantillas. Para no repetir código y estructurar nuestra página de forma correcta. Hasta ahora creabamos una página JSP que contenía todo el código: cabecera, menú lateral, pie y centro. Pero, ¿que sucede si quiero crear una nueva página que tenga la misma cabecera, menú y pie, pero con distinta parte central? Pues que si no utilizamos plantillas y obviamos el uso de la librería de etiquetas que viene con JSP, tendríamos que copiar el mismo código.

Para evitar esta situación aparece Apache Tiles que, como se indica en su página, es un marco de plantillas diseñado para simplificar el desarrollo de interfaces de usuario de aplicaciones Web. Tiles permite definir a los autores de la página fragmentos (tiles) que pueden montarse en una página completa en tiempo de ejecución. Estos fragmentos se pueden utilizar simplemente con el fin de reducir la duplicación de los elementos de la página o para desarrollar una serie de plantillas reutilizables. Estas plantillas agilizan el desarrollo de una aplicación completa.

Tiles creció en popularidad como un componente de  Struts. Posteriormente fue extraído de Struts y ahora está integrado con diversos frameworks.

Lo primero que haremos será instalar Tiles en nuestra aplicación. El concepto de instalación en Tomcat es muy sencillo. Descargarse las librerías (.jar) y colocarlas en la carpeta WEB-INF\lib. También se pueden poner en la carpeta lib del servidor para que sean compartidas por todas las aplicaciones.

Como la instalación está muy bien explicada en la página oficial os remito a ella. (Instalación de Tiles).

El siguiente paso es configurar la aplicación para que utilice Tiles. En la web (sección «Startup with initialization parameters») se explica cómo configurar el fichero web.xml y crear un fichero de definición de plantillas (sección «Create a definition»). No se debe olvidar poner las etiquetas servlet y listener en el fichero web.xml.

Una vez realizada la instalación y la configuración vamos a crear nuestro primer diseño. En esta sección se explica cómo hacerlo. El último paso nos pide que insertemos la definición en una JSP, nosotros haremos lo siguiente:

  1. Creamos el fichero \jsp\inicio.jsp
  2. Insertamos el siguiente código:
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<tiles:insertDefinition name="myapp.homepage" />

¿Y que hemos hecho aquí? Pues cerrar el circulo. Estamos diciendo en inicio.jsp que se incluya la librería http://tiles… con el prefijo tiles y que en una parte de la página se inserte la definición myapp.homepage. Esta se encuentra en el fichero tiles-defs.xml que se configuró en el web.xml de la siguiente forma:

<tiles-definitions>
  <definition name="myapp.homepage" template="/layouts/classic.jsp">
    <put-attribute name="title" value="Tiles tutorial homepage" />
    <put-attribute name="header" value="/tiles/banner.jsp" />
    <put-attribute name="menu" value="/tiles/common_menu.jsp" />
    <put-attribute name="body" value="/tiles/home_body.jsp" />
    <put-attribute name="footer" value="/tiles/credits.jsp" />
  </definition>
</tiles-definitions>

Una definición tiene dos partes: una plantilla (layout) y las fragmentos (tiles o azulejos) que la componen. De tal forma que para el mismo layout se pueden poner distintos «azulejos». Por ejemplo, myapp.homepage utiliza /layouts/clasicc.jsp como plantilla y pone /tiles/home_body.jsp como cuerpo de la página. Podríamos crear otra definición, myapp.navidades, que utilice el mismo layout pero que ponga como body /tiles/navidades.body.jsp.

De esta forma conseguimos reutilizar partes del diseño, cabeceras, menús, pie, etc.

Pero hasta ahora no hemos hecho nada que no se pueda conseguir con la librería de etiquetas <jsp:> que viene por defecto en la instalación de Tomcat. Pero Tiles  es algo más, pudiendo anidar definiciones, usar expresiones, comodines, composición dinámica, etc. Aquí están todos.

Sólo voy a hablar de dos: comodines y composición dinámica.

Comodines

Las definiciones se han creado poniendo las partes que la componen, pero se pueden utilizar comodines de la siguiente forma:

<definition name="test.definition*.message*" template="/layout{1}.jsp">
    <put-attribute name="title"  value="This definition has a message: {2}."/>
    <put-attribute name="header" value="/header.jsp"/>
    <put-attribute name="body"   value="/body.jsp"/>
</definition>

Para esta definición, «test.definition*.message*» , se ha utilizado la plantilla /layout{1}.jsp. ¿Para que se utilizan esos * puestos en el nombre de la definición? ¿Qué significan {1} {2}? Lo entederemos más facilmente al ver cómo se utiliza la definición.

<tiles:insertDefinition name="test.definitionOne.messageThisIsAMessage" />

Si nos fijamos en el nombre de la definición, «test.definitionOne.messageThisIsAMessage«, nos damos cuenta de que es distinto al utilizado al definirla. ¿Que hace Tiles con los textos que han «aparecido»? Pues sustituye el primero, One, por {1} y el segundo «ThisIsAMessage» por {2}. De tal forma que la plantilla utilizada será /layoutOne.jsp y el texto del atributo title será «ThisIsAMessage«.

Si en una página jsp específica queremos utilizar la misma definición pero cambiando de plantilla pondremos:

<tiles:insertDefinition name="test.definitionOtra.messageElTitulo" />

Composición dinámica

La parte más interesante de Tiles es que se puede establecer dinámicamente los fragmentos que componen una definición. Hay dos formas de hacerlo, con JSP o en el servlet (mediante APIS).

Si en nuestro servlet Control ponemos este código:

		TilesContainer container = ServletUtil.getContainer(
		        req.getSession().getServletContext());

		AttributeContext attributeContext = container.startContext(req,
		        resp);
		attributeContext.putAttribute("body",new Attribute("/jsp/tiles/body.jsp"));
		container.render("myapp.homepage", req, resp);
		container.endContext(req, resp);

Estaremos modificando el atributo body con el valor deseado para la plantilla my_template.jsp. Por lo que en tiempo de ejecución se establece el fragmento.

Pero en eclipse sale un error ya que no encuentra la clase TilesAttributeContext. Deberemos incluir el jar correspondiente para que desaparezca.

Etiquetas: ,

6 Respuestas a “Apache Tiles, un sistema de plantillas”

  1. Isra dice:

    Pues que si no utilizamos plantillas y obviamos el uso de la librería de etiquetas que viene con JSP, tendríamos que copiar el mismo código.

    No necesariamente, para eso están los include de JSP.

  2. Miguel Angel dice:

    Por eso en la frase pone «obviamos el uso de la librería de etiquetas»

  3. David Bernad dice:

    Hola Miguel Ángel,

    ¿tú sabes si se puede añadir una sentencia if en el tiles-config.xml?
    Lo pregunto porque tengo que añadir un archivo css en un layout pero sólo cuando el browser sea IE.

    Gracias, un saludo.

  4. Miguel Angel dice:

    Hola David,

    Desconozco si en el tiles-def puedes poner un if. Apostaría fuerte a que no. Ya que es un xml, tendría que estar definido como un atributo y no recuerdo que lo esté.

    Puedes poner un atributo en la definición que sea la css, en la jsp donde la insertes le pongas una u otra hoja dependiendo del navegador.

    Un saludo,

  5. Mauricio Rueda dice:

    Saludos!!!

    Soy nuevo en esto y he tratado de seguir los pasos q has propuestos pero tengo unas dudas.

    Donde esta el archivo tile-def.xml?
    Cual es el codigo de este archivo?

    explicame porfavor
    gracias

  6. Miguel Angel dice:

    El archivo tiles-def está en /WEB-INF/

    y el código es el que pone en http://tiles.apache.org/framework/tutorial/basic/pages.html sección «Create a definition»

    salu2

Dejar una respuesta