March 1, 2021
Hot Topics:

Struts in Action: Developing Applications with Tiles

  • By Manning Publications Co.
  • Send Email »
  • More Articles »

11.5.4 Refactoring a page with <tiles:insert>

As with any refactoring, it's best to start slow, making one small change after another, until the first iteration is complete. As the process continues, you can take larger and larger steps, building on the prior work (and learning from your mistakes).

In most cases, the goal will be to reduce the pages to a Definition that can be declared in the Tiles configuration file and called from within an ActionForward (see section 11.3 for details). This approach saves creating an extra punch list page to insert the tiles. But to get started, it's simplest to build a page using the <tiles:insert> tags.

To get off on the right foot, remember to:

  • Select a good starter page.
  • Thoughtfully extract the tiles from that page.
  • Develop a set of good (and bad) practices along the way.
Selecting a good starter page

It's best to start with a simple page, extract the common components, and insert them one at a time back into the original page. Your application's welcome or logon page can be a good candidate. These tend to be relatively simple pages with a nice mix of reusable and custom content. An interior page can also be a good choice, if it does not contain too much chrome. Listing 11.13 shows an interior page from the Artimus example application [ASF, Artimus] before it was migrated to Tiles.

Listing 11.13 Our starter page: /pages/View.jsp

<%@ taglib uri="/tags/struts-html" prefix="html" %><%@ taglib uri="/tags/struts-bean" prefix="bean" %><%@ taglib uri="/tags/struts-logic" prefix="logic" %><%@ taglib uri="/tags/request" prefix="req" %><!-- HEADER --><HTML><HEAD><html:base/><LINK rel="stylesheet" type="text/css" href="<html:rewriteforward='baseStyle'/>"><TITLE>Artimus - Article</TITLE></HEAD><BODY><TABLE class="outer"><TR><TD><TABLE class="inner"><!-- MESSAGE --><TR><TD class="message" colspan="3" width="100%">                    <html:errors/></TD></TR><TR><TD class="heading" colspan="3"><H2><bean:write name="articleForm" property="title"/&lg</H2></TD></TR><TR><TD class="author" colspan="3">by <bean:write name="articleForm"                   property="creator"/></TD></TR><TR><TD class="article" colspan="3"><bean:write name="articleForm" property="content"                               filter="false"/></TD></TR><%-- CONTRIBUTOR PANEL --%><req:isUserInRole role="contributor"><TR><TD colspan="3"><HR /></TD></TR><TR><%-- DELETE --%><logic:equal name="articleForm" property="marked" value="0"><html:form action="/admin/article/Delete"><TD class="input"><html:submit >DELETE</html:submit></TD><html:hidden property="article"/></html:form></logic:equal><%-- RESTORE --%><logic:equal name="articleForm" property="marked" value="1"><html:form action="/admin/article/Restore"><TD class="input"><html:submit>RESTORE</html:submit></TD><html:hidden property="article"/></html:form></logic:equal><html:form action="/admin/article/Edit"><TD class="button" colspan="2"><html:hidden property="article"/><html:submit>EDIT</html:submit><html:cancel>CANCEL</html:cancel></TD></html:form></TR></req:isUserInRole><!-- NAVBAR --></TABLE></TD></TR><TR><TD class="navbar"><html:link forward="done">DONE</html:link></TD></TR></TABLE></BODY><    /HTML>

Once you've selected your starter page, go through it and extract each logical block into its own tile and insert it back again. After each extraction, test the page to be sure it still renders. Listing 11.14 shows a fragment extracted into its own tile.

Listing 11.14 An extracted tile: /tiles/header.jsp

<%@ taglib uri="/tags/struts-html" prefix="html" %><HTML><HEAD><html:base/><LINK rel="stylesheet" type="text/css" href="<html:rewrite      forward='baseStyle'/>"><TITLE>Artimus - View Article</TITLE></HEAD><BODY onload="document.forms[0].elements[0].focus();"><!-- OUTER TABLE --><TABLE class="outer"><TR><TD align="center"><!-- INNER TABLE --><TABLE class="inner"><TR><TD class="navbar" colspan="3">View Article</TD></TR>

Listing 11.15 shows how the View.jsp can include the Header tile again after it has been extracted.

Listing 11.15 Inserting an extracted tile: /pages/article/View.jsp

<%@ taglib uri="/tags/struts-html" prefix="html" %><%@ taglib uri="/tags/struts-bean" prefix="bean" %><%@ taglib uri="/tags/struts-logic" prefix="logic" %><%@ taglib uri="/tags/tiles" prefix="tiles" %><%@ taglib uri="/tags/request" prefix="req" %><!-- HEAD --><tiles:insert page="/tiles/header.jsp"/><!-- MESSAGE --><TR><TD class="message" colspan="3" width="100%"><html:errors/></TD></TR><!-- ... --></HTML>

As soon as your first tile is extracted and inserted back, be sure to test opening the page before moving on to the next tile.

When this process is complete, the page will consist of a series of insert tiles, as shown in listing 11.16.

Listing 11.16 A refactored page: /pages/View.jsp (completed)

<%@ taglib uri="/tags/tiles" prefix="tiles" %><tiles:insert page="/tiles/header.jsp"/><tiles:insert page="/tiles/message.jsp"/><tiles:insert page="/tiles/view.jsp"/><tiles:insert page="/tiles/navbar.jsp"/>

If the text in some of the tiles has to be customized, say with the page title, you can use the <tiles:put> tag to send a custom value along to the tile. The <tiles:getAsString> tag can then write it out when the page renders. Listing 11.17 shows how to send the text to the tile; listing 11.18 shows how to write the dynamic text out again.

Listing 11.17 Inserting dynamic content: /pages/View.jsp (revised)

<%@ taglib uri="/tags/tiles" prefix="tiles" %><tiles:insert page="/tiles/header.jsp"><tiles:put name="title" value ="Artimus - View Article"/><tiles:put name="subtitle" value ="View Article"/></tiles:insert><tiles:insert page="/tiles/message.jsp"/><tiles:insert page="/tiles/view.jsp"/><tiles:insert page="/tiles/navbar.jsp"/>

Listing 11.18 Writing dynamic content with getAsString

<%@ taglib uri="/tags/struts-html" prefix="html" %><%@ taglib uri="/tags/tiles" prefix="tiles" %><HTML><HEAD><html:base/><LINK rel="stylesheet" type="text/css" href="<html:rewrite      forward='baseStyle'/>"><TITLE><tiles:getAsString name="title"/></TITLE></HEAD><BODY onload="document.forms[0].elements[0].focus();"><!-- OUTER TABLE --><TABLE class="outer"><TR><TD align="center"><!-- INNER TABLE --><TABLE class="inner"><TR><TD class="navbar" colspan="3">    <tiles:getAsString name="subtitle"/></TD></TR>

If you prefer, the Struts <bean:write> or <bean:message> tag can also be substituted for <tiles:getAsString>. The attributes are being saved to the standard contexts, so any standard tag will work as well.

Extracting tiles

The main work of the refactoring is to determine which part of the page is part of which tile, moving that fragment into its own file and then inserting it back again. Here's a step-by-step checklist:

  1. Select and cut the block.
  2. Open a new file.
  3. Paste in the block.
  4. Save and name the file as a JSP (or HTML file if you can).
  5. Insert any taglib import statements the tile requires.
  6. Close the new tile.
  7. Place a <tile:insert page="/path/to/new/page"/> tag where the segment used to be.
NOTE     The Tiles Definitions represent the set of pages that were in use before the refactoring began. The pages are being composed differently, but the content and appearance should remain the same. Most often, the Definition includes a body or content tile as part of the Definition. Some distinct pages may not have a unique tile but are represented by a unique list of shared tiles. You may have a form that uses different buttons under different circumstances. One page may include the set of buttons for creating a new record. Another page may include the set of buttons for updating a record. But other pages may share the sets of buttons and other tiles in the Definition. Distinct pages may also be created from the same Definition by passing a title string and the dynamic content retrieved from a data service. You might have several different ways of searching for records but display them all using the same Definition.

Page 7 of 9

This article was originally published on April 17, 2003

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date