Internationalizing Tiles


Using Tiles

Using the Tiles framework involves these five steps:

  1. Enable the Tiles plugin.

  2. Create Tiles definitions.

  3. Create layout JSPs and use the Tiles Tag Library.

  4. Create content JSPs to fill in the layout JSPs.

  5. Use the Tiles definitions.

The following sections explain how to configure and use Tiles in detail.

Enabling the Tiles Plugin

Although Tiles comes packaged with Struts, by default Tiles is not enabled. To enable and use Tiles, you have to add the following <plug-in> definition to your application's Struts configuration file (e.g., struts-config.xml) file:

<!-- Tiles Configuration --> <plug-in className="org.apache.struts.tiles.TilesPlugin">   <set-property property="definitions-config"                    value="/WEB-INF/tiles-defs.xml"/> </plug-in>

This definition causes Struts to load and initialize the Tiles plugin for your application. Upon initialization, the plugin loads the comma-delimited list of Tiles configuration files specified by the definitions-config property. Each configuration file's path should be specified using a Web application-relative path, as shown in the preceding example.

Note that your application's Struts configuration file must conform to the Struts Configuration DTD, which specifies the order in which elements are to appear in the file. Because of this, you must place the Tiles <plug-in> definition in the proper place in the file. The easiest way to ensure that you are properly ordering elements in the file is to use a tool like Struts Console that automatically formats your configuration file so that it conforms to the DTD.

In version 1.3 Struts moved away from using the RequestProcessor for customized request processing to using a Jakarta Commons Chain-based solution. As a result of this change, Tiles no longer extends the base Struts RequestProcessor to implement its functionality. Instead Tiles now uses a custom chain command and custom chain configuration file with the custom command enabled to handle its processing. For Struts versions 1.3 and later, you must configure the Struts ActionServlet definition in the web. xml file to use a Tiles-specific chain configuration file. Following is an example of the necessary servlet configuration with the additional configuration details in bold:

<servlet>   <servlet-name>action</servlet-name>   <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>   <init-param>     <param-name>config</param-name>     <param-value>/WEB-INF/struts-config.xml</param-value>   </init-param>   <init-param>     <param-name>chainConfig</param-name>     <param-value>org/apache/struts/tiles/chain-config.xml</param-value>   </init-param>   <load-on-startup>1</load-on-startup> </servlet>

This will cause Struts to load the Tiles-specific chain-config.xml file from the Tiles .jar file (e.g., struts-tiles-1.3.5.jar).

Creating Tiles Definitions

There are two ways that you can create Tiles definitions and specify their attributes for your application. First, you can define them in a Tiles XML configuration file. Second, you can define them inside JSPs using the Tiles Tag Library. Each approach is described here, along with information on extending definitions, and information on how to use definitions as attribute values.

XML Configuration File–Based Definitions and Attributes

The first, and most often used, way that you can define Tiles definitions and attributes is by placing them in an XML configuration file typically named tiles-defs.xml. Of course, you can use another name for the file, but that is the standard name. Upon application startup, Tiles loads this file and places its definitions into memory. Following is a basic example of how to define a definition in a Tiles configuration file:

<?xml version="1.0"?>     <!DOCTYPE tiles-definitions PUBLIC   "-//Apache Software Foundation//DTD Tiles Configuration 1.3//EN"   "http://struts.apache.org/dtds/tiles-config_1_3.dtd">     <tiles-definitions>   <definition name="search.page" path="/mainLayout.jsp">     <put name="header" value="/header.jsp"/>     <put name="body"   value="/search.jsp"/>     <put name="footer" value="/footer.jsp" />   </definition> </tiles-definitions>

Each definition in the tiles-defs.xml file has its own definition that is declared with a definition tag. The definition tag assigns a logical name to the definition, with the name attribute, and specifies the path to a layout JSP for the definition, with the path attribute. The logical name given to the definition will be used to refer to the definition inside JSPs and the Struts configuration file. Nested inside the definition tag, put tags are used to specify the definition's list of attributes.

Note 

Detailed information on the Tiles configuration file is found in Chapter 19.

JSP-Based Definitions and Attributes

The second way that you can define a Tiles definition and its attributes is by specifying them with Tiles Tag Library tags inside JSPs. Following is a basic definition defined in a JSP:

<%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles" %>     <tiles:definition  template="/mainLayout.jsp" >   <tiles:put name="header" value="/header.jsp" />   <tiles:put name="body"   value="/search.jsp" />   <tiles:put name="footer" value="/footer.jsp" /> </tiles:definition>

This definition will be stored in a page scope JSP variable named search.page (as specified by the id attribute of the definition tag) so that it can be accessed from other tags. To use this JSP-based definition, you must use the Tiles insert tag, as shown next:

<tiles:insert beanName="search.page" flush="true"/>

Because the definition tag stores the definition in a JSP scripting variable, you must use the beanName attribute of the insert tag to specify the definition. This differs from the way in which you would insert a definition defined in a Tiles configuration file.

The idea behind defining Tiles definitions inside JSPs is that you can define several definitions in a "layout configuration" JSP and then include that JSP in every JSP that uses the definitions. Thus, a layout configuration JSP is similar in purpose to a Tiles configuration file.

Extending Definitions

A powerful and often-used feature of definitions is the ability to have one definition extend another. This functionality is similar to the way inheritance works in Java. When defining a definition, you can specify that the definition extends another definition, instead of specifying a layout JSP for the definition. The child definition inherits the layout JSP and attributes of the parent and can override any of the parent attributes as well as add its own attributes. For example, you may want to have a master layout definition for your site that all other definitions extend from. The master definition can specify values for the attributes that are common across all pages. The child definitions can then specify values for just the attributes that are unique to that page. Additionally, child definitions can override any of the master definitions' common attribute values when necessary, such as for a page that needs a unique header or footer. Following is an example Tiles configuration file that illustrates a few definition-extending scenarios:

<?xml version="1.0"?>     <!DOCTYPE tiles-definitions PUBLIC   "-//Apache Software Foundation//DTD Tiles Configuration 1.3//EN"   "http://struts.apache.org/dtds/tiles-config_1_3.dtd">     <tiles-definitions>       <!-- Main Layout -->   <definition name="main.layout" path="/mainLayout.jsp">     <put name="title"  value=""/>     <put name="header" value="/header.jsp"/>     <put name="menu"   value="/menu.jsp"/>     <put name="body"   value=""/>     <put name="footer" value="/footer.jsp" />   </definition>       <!-- Search Page -->   <definition name="search.page" extends="main.layout">     <put name="title"  value="Search Page"/>     <put name="body"   value="/search.jsp"/>   </definition>       <!-- Employee Layout -->   <definition name="employee.layout" extends="main.layout">     <put name="menu"  value="/employee/menu.jsp"/>   </definition>       <!-- Employee Edit Page -->   <definition name="employeeEdit.page" extends="employee.layout">     <put name="title"  value="Employee Edit Page"/>     <put name="body"   value="/employee/edit.jsp"/>   </definition>     </tiles-definitions>

As stated, this file contains a few different extension scenarios. First, the file declares the main layout from which the other definitions will extend. This layout specifies values for the attributes that will be common across most pages. However, it purposely leaves the page-specific attributes' values blank, because they will be overridden by extending definitions. The first extending definition, search.page, extends the main layout definition and provides values for the title and body attributes. The rest of the attributes that are necessary to fill in the main layout will be inherited from the main layout definition. At run time, when the search.page definition is used, Tiles will use the mainLayout.jsp file and populate it with content from the child and parent definitions, as appropriate.

The second definition-extension scenario represented in the preceding configuration file creates a specific layout by extending the generic main layout and customizing it. The employee.layout definition extends the main layout and overrides the menu attribute's value to create a new employee-specific layout. Note that the menu attribute points to an employee-specific menu JSP. The employeeEdit.page definition extends the employee.layout layout definition. This final definition, like the search.page definition, specifies values for the title and body attributes. The rest of the attribute values that are necessary to populate the layout JSP are inherited from the parent definition.

Note that Tiles supports an essentially unlimited number of definition extensions. Thus, you could create a generic master definition followed by several more specific definitions that extend it. Then, you could add yet another level of definitions that extend the extended definitions to create even more specific page definitions. This is a very powerful feature and is the key advantage that Tiles has over JSP includes.

Using Tiles Definitions as Attribute Values

Another feature of the Tiles framework is the ability to use definitions as the value for an attribute. This feature allows pages to be constructed in a hierarchical fashion. For instance, you can define a master layout that has a menu attribute and, instead of specifying the URL to a JSP as the value for the attribute, specify the name of another definition. A sample configuration file for this scenario is shown next:

<?xml version="1.0"?>     <!DOCTYPE tiles-definitions PUBLIC   "-//Apache Software Foundation//DTD Tiles Configuration 1.3//EN"   "http://struts.apache.org/dtds/tiles-config_1_3.dtd">     <tiles-definitions>       <!-- Main Layout -->   <definition name="main.layout" path="/mainLayout.jsp">     <put name="title"  value=""/>     <put name="header" value="/header.jsp"/>     <put name="menu"   value="/menu.jsp"/>     <put name="body"   value=""/>     <put name="footer" value="/footer.jsp" />   </definition>       <!-- Search Page -->   <definition name="search.page" extends="main.layout">     <put name="title"  value="Search Page"/>     <put name="body"   value="/search.jsp"/>   </definition>       <!-- Employee Layout -->   <definition name="employee.layout" extends="main.layout">     <put name="menu"  value="/employee/menu.jsp"/>   </definition>       <!-- Employee Edit Page -->   <definition name="employeeEdit.page" extends="employee.layout">     <put name="title"  value="Employee Edit Page"/>     <put name="body"   value="/employee/edit.jsp"/>   </definition>     </tiles-definitions> 

In this scenario, the main.layout definition has a menu attribute whose value points to the name of another definition, menu.layout. Tiles intelligently determines the type of value each attribute has and processes its content accordingly. Thus, if an attribute is set to a JSP, then Tiles will use a JSP. If the attribute is set to the name of a definition, Tiles will recognize that and use the definition. This feature allows you to create sophisticated layouts that maximize content reuse.

Creating Layout JSPs and Using the Tiles Tag Library

Creating layout JSPs with the Tiles Tag Library is similar to the way you would go about creating JSPs that leverage JSP's include mechanism. Simply place your layout page's HTML in the JSP and then use Tiles Tag Library tags to source in content. The HTML creates a template (or wire frame) for a page and the Tiles tags act as placeholders for content that will be inserted into the template at run time. Following is a basic layout JSP that illustrates how this works:

<%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles" %>     <html> <head> <title><tiles:getAsString name="title"/></title> </head> <body>     <tiles:insert attribute="header"/>     <table> <tr> <td width="20%"><tiles:insert attribute="menu"/></td> <td width="80%"><tiles:insert attribute="body"/></td> </tr> </table>     <tiles:insert attribute="footer"/>     </body> </html>

At run time, when a definition uses this layout, it will make a set of attributes available to the page to be inserted with the Tiles Tag Library's insert tag.

Note 

A complete overview of the Tiles Tag Library is given later in this chapter, beginning in the section "Using the Tiles Tag Library."

Creating Content JSPs

Content JSPs are used to fill in the placeholders created by layouts. These JSPs simply contain the HTML necessary to fill in a specific section of a layout. You create these JSPs the same way you would create JSPs that are used for includes. You don't, however, specifically source in any of these JSPs into the layout JSPs, as you would if you were using includes. Instead, layout JSPs use Tiles tags to insert attributes whose values point to these content JSPs.

Using the Tiles Definitions

Once you have created Tiles layout JSPs and have defined definitions that use them, you can put the definitions to use. There are two different ways to use definitions: you can insert a definition's content into a JSP, or you can use definitions as the targets of Struts forwards.

The following example illustrates how to insert a Tiles definition into a JSP:

<%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles" %>     <html> <head> <title>Employee Search</title> </head> <body>     <font size="+1">ABC, Inc. Human Resources Portal</font><br> <hr width="100%" noshade="true">     <tiles:insert definition="search.page"/>     <hr width="100%" noshade="true">     </body> </html>

As you can see, to insert a definition, you just use the Tiles Tag Library's insert tag. The content specified by the definition will be processed and inserted in its final state (i.e., all levels of layouts will be collapsed into one). This way of using definitions is very powerful because you can insert definitions that comprise a page's whole content, as shown next. Or you could insert definitions that are only intended to fill a portion of a page with content, as was shown in the first example.

<%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles" %>     <tiles:insert definition="search.page"/> 

The second way to use Tiles definitions is to have them be used as the target of Struts forwards. This way works by having the names of definitions be used as forwards. Instead of a forward pointing to a JSP or another URL, it points to the name of a Tiles definition. At run time, when the Tiles plugin is enabled, Tiles intercepts all requests being made through the Struts controller servlet. Tiles does this by inserting itself into the Struts request processing engine. If Tiles sees a forward whose value is the name of a definition, it will handle the request and return the contents of the definition. Following is an example of how to define a forward in the Struts configuration file that uses a Tiles definition:

<global-forwards>   <forward name="search" path="search.page"/> </global-forwards>

Notice that the path attribute specifies the name of a Tiles definition. Tiles will recognize this and handle processing for this forward.

Handling Relative URLS with Tiles

Many page elements such as images, style sheets, and hyperlinks are referred to using relative URLs when developing web applications. Relative URLs are those URLs that are relative to their context (e.g., /rel-dir/image.jpg) instead of being fully qualified (e.g., http://abc.com/appname/rel-dir/image.jpg). Relative URLs can be very useful during development, as they remove the direct reference to a specific domain name and application context, allowing the pages using them to be portable. The problem with relative URLs, though, occurs when a page using a relative URL to a certain path gets moved to somewhere that path is no longer applicable. This scenario is quite common when working with Tiles because there are common include pages and page-specific resources.

To solve the problem of relative URL portability, you can use the rewrite tag from the Struts HTML Tag Library. The rewrite tag ensures that relative URLs are prefixed with the proper application context path. Following are a couple of examples of using the rewrite tag for this purpose:

<img src="/books/1/249/1/html/2/<html:rewrite page='/images/logo.jpg'/>">     <link rel="stylesheet" type="text/css"     href="<html:rewrite page='/css/master.css'/>">



Struts. The Complete Reference
Struts: The Complete Reference, 2nd Edition
ISBN: 0072263865
EAN: 2147483647
Year: 2004
Pages: 165
Authors: James Holmes

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