JSP Page Design With Tiles

By Salman Halim (salmanhalim@hotmail.com)

Introduction

Tiles is a taglib packaged with Jakarta Struts 1.1 (currently in beta stage, but quite stable) and is available as part of the struts package. Struts (1) is an open-source Web application framework available from http://jakarta.apache.org/struts.

Tiles lets the user break the presentation page into small JSP snippets that perform a specific function but are not complete pages in their own rights. Each such snippet becomes known as a tile. Putting these tiles together creates a presentation JSP.

The tiles mechanism has advantages over the basic jsp:include tag in that it is dynamically configurable: an application layout can be defined and portions of it filled in dynamically -- based on values that become known at runtime (such as the current Locale settings, for example).

Tiles can be used on its own; however, it can also be used from within the struts framework. This document will create a simple set of pages with tiles to teach by example; these pages will share a common header, footer and basic layout.

Initial Tiles Installation and Setup

Tiles consists of one taglib (struts-tiles.tld); all the supporting Java classes are contained within the main struts JAR (struts.jar).

A standard taglib entry is placed inside the configuration file (web.xml) of the Web application:


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

Definition of Tiles taglib in web.xml

It is possible to store Tiles definitions inside a centralized XML file (the approach taken in this document). In this case, Tiles needs to be installed as a struts plugin; this basically installs the Tile factory as a plugin, enabling the contents of the tiles definition file to be processed.


<plug-in className="org.apache.struts.tiles.TilesPlugin">
  <set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml"/>
  <set-property property="definitions-debug" value="1"/>
  <set-property property="definitions-parser-details" value="0"/>
  <set-property property="definitions-parser-validate" value="true"/>
</plug-in>

Definition of Tiles plugin in struts-config.xml

Note that the value of the definitions-config property can be a comma-separated list of tile definition files in the event that there are more than one.

To use Tiles in a JSP, simply use the standard taglib tag:


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

Preparing for use of the Tiles taglib inside a JSP

Main Layout

Designing a main tiles layout for use as the page template consists of creating JSP page with placeholders where other pages, tiles layouts or literal strings (such as page titles) will eventually be placed.

Layout JSP

We will use layout.jsp for this application's look. (The source is available here.)

This page basically defines a look for the pages in the application: a title, a header page, a heading, a main body and a footer. The contents of the page will be indented slightly (by being contained in a table) for effect. A breakdown of the significant lines in the source is as follows:


Line Significance

2 Identifies the Tiles taglib to be used on this page.
6 Sets the window title based on dynamically specified text -- varies from page to page.
10 Inserts the content of the dynamically specified header page -- this will probably be the same on every page but may vary as the name of the page is not hard-coded here. Contains common elements like a top menu.
17 Displays the dynamically specified text as a page heading -- varies from page to page and is probably just a longer version of the title.
19 Inserts the contents of the dynamically specified body -- this is where the actual contents of the page in question will go (such as a menu page consisting of anchors or a login form for validation).
26 Inserts the contents of the dynamically specified footer page -- behaves quite similarly to the header and contains common page closing tags such as company logos.

Breakdown of layout.jsp


Notes
  • The tiles get tag causes the value of the name attribute to be treated as either the name of a JSP page or another (sub)layout which is then processed. This processing is recursive in that the JSP page (or the pages specified in the sublayout) may contain further tiles (line 10):
    <tiles:get name="header"/>
  • The getAsString tag, on the other hand, causes the value of the specified attribute to be inserted literally without processing, allowing for specification of page headings and titles (line 6):
    <tiles:getAsString name="title"/>

Tiles configuration

This is the /WEB-INF/tiles-defs.xml file (source) mentioned in the struts-config.xml file.

A description of some of the key lines:


Line Significance

7-19 The main element of a tiles defintion file is tiles-definitions.
8-18 The definition of a layout named mainLayout that will be used by the pages in the application for their appearance. The page corresponding to the layout is defined as layout.jsp.
9, 11 These are values that will be placed into the resulting page as literals (and not interpreted as tile JSP pages); individual pages will obviously override these to suit their page title and headings. These correspond to the getAsString described earlier.
13, 15, 17 These values will be considered to point to either other Tiles layouts or specific JSP pages. (The system will basically try to match the name to a layout; if that fails, it will look for a page with the name instead.) Of these, only the body value is expected to change on a per-page basis, though some pages might want a different header or footer (say, to display user information if the user has logged in). These values correspond to the get tiles tag discussed earlier.

Breakdown of tiles-defs.xml


Notes
  • Values specified using the put tag can be used either as strings or as pages (or layouts); it is entirely up to the page that uses the values to get them as strings or pages.
  • Tiles does in fact allow for setting individual values explicitly as strings for stronger typing purposes (the put tag contains a type attribute that is optional but can be used for explicit typing); the generic way is simply easier. However, if a layout is going to shared across multiple developers, the stronger typing is important to ensure that the attributes are used as intended.

Note that these are merely the default values. Some of these will be changed on a per-page basis while others (such as the header) may be left to the defaults.

There can be several such layouts, allowing for different functionality throughout the application and the values that point to individual pages could just as easily be the names of another such layout defined in the configuration files.

Individual Tiles

Up to now, we have defined a Tiles layout. There aren't, however, any pages that make use of this layout. Before we can create those, we have to create a simple header and footer for use in our final version. The source for header.jsp is available here and the source for footer.jsp is available here. Note how these pages are not completely formed HTML pages -- they are tiles which need to be placed inside a larger composite to create a final page. (2)

Typically, tiles are kept in a separate subdirectory (call it tiles, for example) to differentiate between JSP pages that are either complete in there own right or actually use a tile layout (such as the mainLayout used here).

Finally, we can build a full page from the pieces thus composed (except for the "body" portion which we'll do shortly). Here is mainMenu.jsp (the source is available here):


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

<tiles:insert definition="mainLayout">
  <tiles:put name="title" value="Main Menu"></tiles:put>
  <tiles:put name="heading"><%= session.getAttribute( "pageHeading" ) %></tiles:put>
  <tiles:put name="body" value="menu.jsp"/>
</tiles:insert>

Contents of mainMenu.jsp

The tiles:insert tag causes the insertion of a particular layout at that point in the JSP. If we had wanted to use the default values specified in the tiles-defs.xml file, we would've simply closed this tag without providing content. As it is, we wanted to overwrite several of the vallues to tailor this particular instance to produce a menu.

Of the five values defined in the original layout, only three are being overridden within this instance of the layout (the default header and footer will be used):


Tile attribute Overriding value

title The value ("Main menu") for the window title is hard-coded and specified using the value attribute of the put tag.
heading The value for the page heading is provided by providing body content for the put tag instead of using the value attribute. This allows the use of dynamic JSP content (such as the value of a session variable, as here) to specify the actual value to be passed. (3) This scenario is probably more realistic as hard-coded values in JSP pages do not lend themselves to internationalization (so it is likely that the window title value would also be dynamic).
body The value for the body page (not created yet in this example) is hard-coded here. Remember, this value will not be treated as a string; instead, it will be processed as the name of either another JSP page (as is the case here) or the name of another Tiles layout (which will be resolved recursively).

Overridden layout values in mainMenu.jsp

At this stage, the only thing missing is a tile JSP named menu.jsp. Just like the header and footer pages, this is not going to be a complete JSP. (The source is here.)

Final Results

When a user hits mainMenu.jsp in our application, they will get a nicely formatted and complete HTML page where all the tiles have been placed. Click here to see the generated source and here to see the page. (4)



Footnotes

1. For an article on struts, go to http://www.javaranch.com/newsletter/Mar2002/newslettermar2002.jsp#struts. Also, the Java Frameworks forum here at JavaRanch discusses things like struts. Go back
2. These pages have been kept simple deliberately. In reality, they can contain JSP logic as well as further references to other tiles. Go back
3. Note that there would have to be a session variable called pageHeading set for this particular example to work. However, this can be easily changed to another snippet of code to render this example usable. Go back
4. I've made a few layout changes (indentation of inserted tiles, addition of comments where the tiles were inserted, link format) so the resulting page can be seen as correct HTML. However, the content is as generated. Go back