Web
Guillermo Castro  

The correct usage of Tiles tags

I haven’t been able to continue my regular posting streak because I’ve been really busy at work. Which in a sense, it’s a good thing. I’ve been doing a lot of Struts, Spring, Tiles, etc. stuff, and hopefully I’ll be able to put some tips and tricks that I come up across with.

One of the things that I’ve come up across with, is the correct way to use Tiles. I was having a lot of troubles getting some information from a tile component.

I first had declared my tiles very simple, by having a .main.layout definition, containing a title, header, menu, content and footer attributes. I would then go and extend this definition for any page I’d created, usually overriding the title and the content attributes. My first definition would look like this:

<tiles-definitions>
    <definition name=".base.layout"
        path="/WEB-INF/jsp/baseLayout.jsp">
        <put name="title" value="" />
        <put name="header" value="/WEB-INF/jsp/header.jsp" />
        <put name="menu" value="/WEB-INF/jsp/menu.jsp" />
        <put name="content" value="" />
        <put name="footer" value="/WEB-INF/jsp/footer.jsp" />
    </definition>
    <definition name=".main.page" extends=".base.layout"
        controllerClass="org.javageek.tilestest.MainPageController">
        <put name="title" value="Main Page" />
        <put name="content" value="/WEB-INF/jsp/main.jsp" />
    </definition>
</tiles-definitions>

I would then use the <tiles> taglib to insert my attributes inside my pages. For example, for baseLayout.jsp I would have something like this:

<%@ page language="java" pageEncoding="UTF-8"%>

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

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html:html locale="true">
<head>
<html:base />
<title><tiles:getAsString name="title" /></title>
</head>

<body>
<table width="100%" border="1">

    <tr valign="top">
        <td align="center"><!– Header page information –> <tiles:insert attribute="header" /></td>
    </tr>

    <tr valign="top">
        <td><!– Menu information –> <tiles:insert attribute="menu" /></td>
    </tr>

    <tr valign="middle">
        <td nowrap><!– Body  Content –> <tiles:insert attribute="content" /></td>
    </tr>

    <tr valign="bottom">
        <td><!– Footer information –> <tiles:insert attribute="footer" /></td>
    </tr>

</table>
</body>
</html:html>

Well, what I wanted to do was to use my MainPageController class to make some objects available to my main page as tiles attributes. I tried every seamingly reasonable <tiles> tag to get the objects on the page, and I would always get an error. After almost half a day I gave up and I ended up adding the objects I needed to the request object, but I thought that wasn’t really the best solution.

Then, I came across this mail, and when I read point 9, I knew what I was doing wrong. I was trying to get the attribute inside a jsp that tiles had no notion about, since it was only just another attribute by itself, and my tiles would not propagate inside this jsp. So I figured that the correct way to use tiles, if you want to programmatically add attributes by means of a Controller class, is to define the page you want the attribute inside, and use this definition as the content of the definiton. To put it in an example, this is how my final .main.page tiles-def.xml looks like now:

<tiles-definitions>
    <definition name=".base.layout"
        path="/WEB-INF/jsp/baseLayout.jsp">
        <put name="title" value="" />
        <put name="header" value="/WEB-INF/jsp/header.jsp" />
        <put name="menu" value="/WEB-INF/jsp/menu.jsp" />
        <put name="content" value="" />
        <put name="footer" value="/WEB-INF/jsp/footer.jsp" />
    </definition>
    <definition name=".main.page" extends=".base.layout">
        <put name="title" value="Main Page" />
        <put name="content" value=".main.page.content" />
    </definition>
    <definition name=".main.page.content"
        controllerClass="org.javageek.tilestest.MainPageController"
        page="/WEB-INF/jsp/main.jsp">
    </definition>
</tiles-definitions>

So, by putting the content inside its own definition, and by using the Controller class on this definition, I am now able to get tiles attributes inside my main.jsp page.

3 thoughts on “The correct usage of Tiles tags

  1. ravi

    Quick question, what exactly you have in your Controller class. Any example??

  2. JavaGeek

    Sure, This is what I used for my tests:

    public class MainPageController extends ControllerSupport {
    	private static final Log log = LogFactory.getLog(MainPageController.class);
    	
    	public void execute(ComponentContext tileContext,
    			HttpServletRequest request, HttpServletResponse response,
    			ServletContext servletContext) throws Exception {
    		//Put some test object
    		tileContext.putAttribute("test", new Double("3.141592"));
    		log.info("Added attribute 'test' to tile context");
    	}
    
    }
    

    And this is what I have on the jsp page:

    <%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles"%>
    
    Main Page Content.
    Trying to retrieve test attribute:
  3. Anonymous

    I have a struts web application with five modules. I needed to using with this module to tiles. how to use this?

    i tried in single module with tiles
    IN multiple module i got error

Leave a Reply