November 14, 2003

Struts Tiles

Tiles is a page-assembly framework that is included with the Struts web application framework. I recently started using Tiles and am very happy with the results. The main benefit that I'm getting from Tiles is the ability to follow the "once and only once" rule: define page formatting once, so when the formatting needs to change, it can be done in one place. Here are the steps that I took to integrate Tiles into my web application.

I like to organize my .war archive as follows:

myapp.war
+- images/myImage1.gif
+- images/myImage2.gif
+- layouts/myLayout1.jsp
+- layouts/myLayout2.jsp
+- myPage1.jsp
+- myPage2.jsp
+- tileDefinitions.jsp
+- tiles/footer.jsp
+- tiles/header.jsp
+- tiles/myPage1Body.jsp
+- tiles/myPage2Body.jsp
+- WEB-INF/lib/commons-beanutils.jar
+- WEB-INF/lib/commons-collections.jar
+- WEB-INF/lib/commons-digester.jar
+- WEB-INF/lib/commons-fileupload.jar
+- WEB-INF/lib/commons-lang.jar
+- WEB-INF/lib/commons-logging.jar
+- WEB-INF/lib/commons-validator.jar
+- WEB-INF/lib/jakarta-oro.jar
+- WEB-INF/lib/struts.jar
+- WEB-INF/struts-bean.tld
+- WEB-INF/struts-config.xml
+- WEB-INF/struts-html.tld
+- WEB-INF/struts-logic.tld
+- WEB-INF/struts-nested.tld
+- WEB-INF/struts-template.tld
+- WEB-INF/struts-tiles.tld
+- WEB-INF/web.xml

Add this to web.xml:

<taglib>
   <taglib-uri>/WEB-INF/struts-tiles.tld</taglib-uri>
   <taglib-location>/WEB-INF/struts-tiles.tld</taglib-location>
</taglib>

myPage1.jsp

<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>

<%@ include file="tileDefinitions.jsp" %>

<tiles:insert beanName="myLayout1" beanScope="application" >
   <tiles:put name="body" value="/tiles/myPage1Body.jsp" />
</tiles:insert>

tileDefinitions.jsp

<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>

<logic:notPresent name="myLayout1" scope="application">

<tiles:definition id="myLayout1" page="/layouts/myLayout1.jsp"
scope="application">
   <tiles:put name="header" value="/tiles/header.jsp" />
   <tiles:put name="body" value="" />
   <tiles:put name="footer" value="/tiles/footer.jsp" />
</tiles:definition>

<tiles:definition id="myLayout2" page="/layouts/myLayout2.jsp"
scope="application">
   <tiles:put name="header" value="/tiles/header.jsp" />
   <tiles:put name="body" value="" />
   <tiles:put name="footer" value="/tiles/footer.jsp" />
</tiles:definition>

</logic:notPresent>

myLayout1.jsp

<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>

<tiles:insert attribute="header" />

<tiles:insert attribute="body" />

<tiles:insert attribute="footer" />

Tile pages

header.jsp, footer.jsp, myPage1Body.jsp, and myPage2Body.jsp are just regular JSP pages that hold the content for a header, footer, and different bodies respectively.

This example uses a JSP page to declare tile definitions (tileDefinitions.jsp). Struts also allows tile definitions to be declared in an XML file. Then, tile definitions can be used as ActionForwards in your struts config file. However, the XML file approach can't be used if you have hard-coded URLs appearing as links in any of your JSP pages, such as in a navigation bar. Therefore, I prefer to use a JSP page to declare my tile definitions. One disadvantage of using a JSP page to declare tile definitions is that one page layout cannot extend another layout (a feature that is available if you declare your layouts in an XML file).

Posted by tomlauren at November 14, 2003 11:37 PM
Comments