Creating a Definition

 < Day Day Up > 



The problem with quote.jsp and index.jsp is that they break the DRY rule: They repeat the header and footer parameter definitions. They use the same parameter values, so it would be nice if we did not have to repeat those parameters for both pages.

If this were a real application, the Tile layout would likely have a lot more regions (say, eight regions) and a lot more pages. It would be a real pain to repeat every one of these parameters every time you wanted to use a Tile layout. Because most pages will use the same header and footer, our goal is to define them in one place instead of in each page.

As you'll recall, earlier we compared the Tile layout to a display function. You invoke the Tile layout using tiles:insert. You pass in parameters using tiles:put. The parameters are other JSP pages and strings that can be inserted into regions of the Tile layout.

What you need now is the ability to define default parameters that correspond to the header and footer regions. The Tiles framework also allows you to pass default arguments to a Tile layout using definitions.

In this section, we show you how to create and use definitions. Definitions specify default parameters for Tile layouts. You can create definitions in JSP or XML. By the end of this section, you will be able to do both.

Creating and Using a JSP Definition

The simplest way to create a definition is with the JSPs. This approach requires the least amount of configuration.

Creating a JSP Tile Definition

To create a JSP definition, follow these steps:

  1. Import the Tiles tag library using the taglib directive.

  2. Ensure that the definition is created only once using the logic:notPresent tag.

  3. Define the definition with the tiles:definition tag and pass the JSP that defines the Tile layout and the scope of the newly created definition.

  4. Define the default parameters with the tiles:put tag.

The siteLayoutDefinition.jsp page (Listing 13.2) creates a definition that uses the siteLayout.jsp page as the Tile layout and specifies default values for the header and footer parameters (as well as other parameters).

Listing 13.2: siteLayoutDefinition.jsp.

start example
 <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %> <logic:notPresent name="siteLayoutDef" scope="application">   <tiles:definition                      page="/siteLayout.jsp"                     scope="application">     <tiles:put name="title" type="string"                      value="WROX Stock Quote System" />     <tiles:put name="header" value="/header.jsp" />     <tiles:put name="footer" value="/footer.jsp" />     <tiles:put name="content" type="string">        Content goes here     </tiles:put>   </tiles:definition> </logic:notPresent> 
end example

The tiles:definition tag defines a JavaBean of type ComponentDefinition (org.apache.struts.tiles.ComponentDefinition). ComponentDefinition has getter and setters for all of the attributes that you can pass it. The logic:notPresent tag ensures that the ComponentDefinition is created only once per application by checking to see if it is already in scope before defining it.

start sidebar

Notice that we define default parameters for the content and title as well. This is considered bad practice. Why? If someone forgets to use the title, he or she will get the default. Because the title should change for every page, we should not define a default for it. This way, if someone forgets to pass the title the Tile layout will fail. In order for it to fail, you need to do two things. First, don't define a default in the definition. Second, don't set ignore equal to true when defining the region in the Tile layout with the tiles:insert tag.

end sidebar

Using a JSP Tile Definition

Using a Tile definition is not much different than using a Tile layout directly. The only differences are that you will specify the definition instead of the Tile layout JSP page and that you will pass in fewer parameters with tiles:put.

To use a Tile definition, follow these steps:

  1. Import the Tiles taglib with the taglib directive.

  2. Include the JSP page that creates the definition by using jsp:include.

  3. Use the tiles:insert tag, but specify the definition bean name and scope instead of the Tile layout page.

  4. Use the tiles:put attribute to specify the title and content but not header and footer parameters.

Here is an example of using a Tiles definition (index2.jsp):

    <%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>    <jsp:include page="siteLayoutDefinition.jsp"/>    <tiles:insert beanName="siteLayoutDef" beanScope="application">        <tiles:put name="title" type="string"                   value="Get WROX Stock Quote 2" />        <tiles:put name="content" value="indexContent2.jsp"/> </tiles:insert> 

Notice that in this example we specify the definition that we created in the previous section with the beanName attribute (siteLayoutDef). The beanName attribute value corresponds to the id attribute value of the bean definition in the previous section. Also note that here we specify two parameters with tiles:put instead of four. This means less typing—and less code to maintain. The joys of DRY...

Do you see a problem here? We have a lot of JSP pages to create: one for the definition (siteLayoutDefinition.jsp), one for the content (indexContent.jsp), one for the index.jsp itself, one for the layout (siteLayout.jsp), one for the header, and one for the footer. Whew! Sum it up and you get six JSP pages instead of one (and this is a simple example). Granted, you are getting a lot of reusability, but it appears that you get this advantage at the expense of simplicity.

Another thing you should note about this example is the definition itself. JSP pages are meant to express visual things in a document-centric fashion. There is nothing inherently visual about the definition. In fact, it is mostly just configuration data. A layout may have several sets of definitions; it would be a hassle to have a JSP page for each. Wouldn't it be nice to have all of this configuration data in one location?

start sidebar

If you have worked with Tiles, you may have seen examples that use the include directive (@page include) instead of the dynamic include action (jsp:include). I prefer jsp:include. The problem I have found with the include directive is that it takes place at translation time and unless the page that includes it changes, the new JSP definition will not be redefined. Save yourself some development hassles and use the jsp:include action instead. The performance difference is negligible (the directive is slightly faster), but the pain of dated JSP definitions is mind-boggling.

end sidebar

Creating and Using an XML Definition

XML definitions are the answer to problems related to the explosion of nonvisual JSPs. Instead of creating one definition per JSP, you can build all of your definitions in one configuration file. Before you can start using XML definitions, you need to install the corresponding Tiles Plugin for Struts. Add the following to your Struts configuration file:

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

The definition-config property specifies the XML file that will contain the XML-based definitions. The code also specifies that the Tiles engine is module aware and that it validates the XML file.

Creating an XML Tile Definition

Creating an XML definition is easy using the Plugin. All you have to do is add another entry in the Tiles definition file (tiles-def.xml, for our example) as follows:

 <tiles-definitions>   <definition name="siteLayoutDef" path="/siteLayout.jsp">     <put name="title" value="WROX Stock Quote System" />     <put name="header" value="/header.jsp" />     <put name="footer" value="/footer.jsp" />     <put name="content" type="string">        Content goes here     </put>   </definition> ... 

The root element is tiles-definitions; all of the Tile definitions for this module will be defined inside this element.

The definition element specifies a Tile definition. The definition we created here is functionally equivalent to the JSP version we defined earlier. Notice that the attributes of the definition are a little different; you use name instead of id and path instead of page. If you know how to define a JSP-based definition, then defining an XML-based one is child's play because they are nearly identical in form and function.

Using an XML Tile Definition

Now that you have defined your XML definition, you need to change quote.jsp and index.jsp to use it. Using the definition is not much different than before, as shown here (index3.jsp). The only difference is the attributes you pass the tiles:insert tag:

 <%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %> <tiles:insert definition="siteLayoutDef">     <tiles:put name="title" type="string"                value="Get WROX Stock Quote 3" />     <tiles:put name="content" value="indexContent3.jsp"/> </tiles:insert> 

You now use the definition attribute to specify the name of the definition created in the Tiles definition file (tiles-def.xml) instead of using beanName and beanScope. You do not have to use jsp:include or logic:notPresent in the definition JSP.

Once you start using XML definitions instead of JSP definitions, life with Tiles gets a little easier. You have to write less code and you won't have as many tiny, nonvisual JSP pages to maintain.



 < Day Day Up > 



Professional Jakarta Struts
Professional Jakarta Struts (Programmer to Programmer)
ISBN: 0764544373
EAN: 2147483647
Year: 2003
Pages: 183

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net