Recipe14.7.Reusing a Common Page Layout with SiteMesh


Recipe 14.7. Reusing a Common Page Layout with SiteMesh

Problem

You want render your application's pages using a common layout without having to change your JSP pages or your application's Struts configuration.

Solution

Use SiteMesh to wrap your application's pages with a common layout and other presentation features.

Discussion

SiteMesh (http://www.opensymphony.com/sitemesh/) is a web-page layout and decoration framework. It allows you to decorate the web pages of an existing application with a common layout. It provides similar features as Tiles but uses a completely different approach. When you use Tiles, you adopt the Tiles-way of doing things by constructing pages using Tiles custom JSP tags, creating definitions in a Tiles configuration file, and linking actions to Tiles using the TilesRequestProcessor. Tiles becomes a pervasive part of your web application.

SiteMesh takes a different approach. It uses a servlet filter to modify the HTTP responses generated by your application, with responses typically generated by JSP pages. SiteMesh amends the response based on settings in a configuration file.

Suppose you have a site with three web pages: a main page, and two secondary pages. The main page looks something like Figure 14-5.

Figure 14-5. Page slated for decoration by SiteMesh


The secondary pages referred to by the two hyperlinks are, like this page, simple. The struts-config.xml file for this application is shown in Example 14-13.

Example 14-13. Struts configuration for sample application
<!DOCTYPE struts-config PUBLIC           "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"           "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd" > <struts-config>     <global-forwards>         <forward name="main" path="/main.do"/>     </global-forwards>     <!--  Action Mapping Definitions  -->     <action-mappings>         <action path="/main"                  type="org.apache.struts.actions.ForwardAction"                  parameter="/WEB-INF/jsps/main.jsp"         />         <action path="/test"                  type="org.apache.struts.actions.ForwardAction"                  parameter="/WEB-INF/jsps/test.jsp"         />         <action path="/summary"                  type="org.apache.struts.actions.ForwardAction"                  parameter="/WEB-INF/jsps/summary.jsp"         />     </action-mappings>     <!-- message resources -->     <message-resources parameter="ApplicationResources"/> </struts-config>

Now your boss comes along and tells you that the site needs to be revised. He wants a titled header across the top of the page, a sidebar with navigation links on the left, and a footer with legalese on the bottom. He also wants the summary page to be displayed in a pop-up window. There are three choices for implementing these changes:

  • Add the new sections to the existing JSPs.

  • Convert your application to use Tiles.

  • Use SiteMesh to adorn the existing site with the new sections.

If your site has only three pages, then the first solution is the most cost effective. However, if your site has 300 pages, the first solution requires changing every page, and the second solution requires refactoring your entire application.

The third solution, using SiteMesh, can be your savior. To install SiteMesh and enable it for your web application, you need to do the following:

  1. Download the SiteMesh full source ZIP file from http://www.opensymphony.com/sitemesh. Version 2.2.1 was used for this recipe. Extract the ZIP file into a directory named something like /sitemesh.

  2. Copy all the JAR files from /sitemesh/lib into your application's WEB-INF/lib directory.

  3. Add the SiteMesh servlet filter and corresponding filter mapping shown in Example 14-14 to your application's web.xml file.

Example 14-14. SiteMesh servlet filter and mapping
<!-- Sitemesh Filter --> <filter>     <filter-name>sitemesh</filter-name>     <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter     </filter-class> </filter> <!-- Sitemesh Filter Mapping --> <filter-mapping>     <filter-name>sitemesh</filter-name>     <url-pattern>/*</url-pattern> </filter-mapping>

  1. Create the decorators.xml file shown in Example 14-15. Save this file to your application's WEB-INF directory.

Example 14-15. SiteMesh decorators configuration file
<decorators defaultdir="/decorators">     <decorator name="main" page="mainDecorator.jsp">         <pattern>*</pattern>     </decorator>     <decorator name="panel" page="panelDecorator.jsp"/>     <decorator name="popup" page="popupDecorator.jsp"/> </decorators>

You are ready to define the decorating content to be added to your existing JSPs. Create the web/decorators directory. This directory, similar to the layouts directory used in a Tiles-based application, contains your decorating JSP pages and stylesheet. Example 14-16 shows the mainDecorator.jsp page.

Example 14-16. Main decorator JSP page
<%@ taglib prefix="decorator" uri="http://www.opensymphony.com/sitemesh/ decorator" %> <%@ taglib prefix="page" uri="http://www.opensymphony.com/sitemesh/page" %> <%@ taglib prefix="bean" uri="http://struts.apache.org/tags-bean" %> <%@ taglib prefix="html" uri="http://struts.apache.org/tags-html" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html>     <head>         <title>             <decorator:title default="{ Unknown Page - shouldn't see this, since                                         pages should define title }" />         </title>         <html:base/>         <link href="decorators/main.css" rel="stylesheet" type="text/css">         <%--pulls the header from the page we are decorating and inserts               it here --%>         <decorator:head />     </head>              <body>         <table width="100%" height="100%">             <tr>                 <td  colspan="2">                    <bean:message key="label.header" />                    </td>             </tr>             <tr>                 <td valign="top" width="20%">                     <%-- grabs the navigation.jsp page and decorates with the                           panel decorator and puts it here --%>                     <page:applyDecorator page="/WEB-INF/jsps/navigation.jsp"                  </td>                 <td>                     <table width="100%" height="100%">                         <tr>                             <td >                                 <div >                                     <%--pulls the title from the page we are                                          decorating and inserts it here --%>                                     <decorator:title />                                 </div>                             </td>                         </tr>                         <tr>                             <td valign="top" height="100%">                                 <%--pulls the body from the page we are                                      decorating and inserts it here --%>                                 <decorator:body />                             </td>                         </tr>                     </table>                 </td>             </tr>             <tr>                 <td  colspan="2">                     <bean:message key="label.footer" />                 </td>             </tr>         </table>     </body> </html>

This decorator page references the "panel" decorator defined by the panelDecorator.jsp page shown in Example 14-17.

Example 14-17. Simple panel decorator
<%@ taglib prefix="decorator" uri="http://www.opensymphony.com/sitemesh/ decorator" %> <decorator:head /> <div >     <span ><decorator:title default="Unknown panel" /></span>     <br/>         <%--inserts the body of whatever we are decorating here --%>     <decorator:body />     </div>

Example 14-18 shows the decorator (popupDecorator.jsp) used for pop-up windows.

Example 14-18. Decorator for a pop-up window
<%@ taglib prefix="decorator" uri="http://www.opensymphony.com/sitemesh/ decorator" %> <html>     <head>         <title><decorator:title default="{ Unknown Page - shouldn't see this,                                   since pages should define title }" />         </title>         <link href="<%= request.getContextPath( ) %>/decorators/main.css"                 rel="stylesheet" type="text/css">         <%--pulls the header from the page we are decorating and              inserts it here --%>         <decorator:head />     </head>          <body>         <div >             <span ><decorator:title                          default="Unknown Title - shouldn't see this" />             </span>             <br/>             <%--inserts the body of whatever we are decorating here --%>             <decorator:body />             </div>     </body> </html>

Finally, Example 14-19 shows the main.css stylesheet, used by the main decorator, you need to create.

Example 14-19. CSS stylesheet for the main decorator
body, td, p {     font-family: verdana, arial, helvetica, sans-serif;     font-size: 12px; } .panelDiv {     border-color: black;     border-width: 2;     border-style: solid;     padding: 4px;     font-size: 12px;     color: black;     background: #C0C0C0;     height: 450px; } .panelTitle {     font-size: 14px;     font-weight: bold; } .popupDiv {    font-family: verdana, arial, helvetica, sans-serif;    font-size: 12px;    background-color:yellow; }  #pageTitle {     background-color: #C0C0C0;     color: black;     font-weight: bold;     font-size: 14px;     border-color: black;     border-width: 1;     border-style: solid;     padding: 3px; } #header {     padding: 5px;     font-size: 16px;     color: White;     font-weight: bold;     background-color: Navy;     text-align: center;     height: 75px; } #footer {     border-color: navy;     border-width: 2;     border-style: solid;     font-size: 10px;     color: black;     font-weight: bold;     text-align: center;     padding-top: 10px;     background: white; }

The only additional JSP page you need to create is for the sidebar navigation. Example 14-20 (navigation.jsp) shows this JSP page.

Example 14-20. Sidebar navigation JSP page
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core"  prefix="c" %> <html>     <head>         <title><bean:message key="title.navigation"/></title>         <script>             function popUp( url ) {                var windowFeatures = "scrollbars=yes,resizable=yes,width=300,                                      height=300";                popUp = window.open(url,"popup",windowFeatures);                popUp.focus( );                 }         </script>     </head>     <body>         <br/>         <c:url var="url" value="/main.do"/>         <a href="<c:out value='${url}'/>">Main Page</a>          <br/><br/>         <c:url var="url" value="/test.do"/>         <a href="<c:out value='${url}'/>">Test Another Page</a>          <br/><br/>         <c:url var="url" value="/summary.do"/>         <a href="<c:out value='${url}'/>">Summary Example</a>          <br/><br/>         <%-- Look at the ParameterDecoratorMapper definition in the          sitemesh.xml, You will see how it takes a decorator parameter          and can take a confirm parameter --%>         <c:url var="url" value="/summary.do">             <c:param name="decorator" value="popup"/>             <c:param name="confirm" value="true"/>         </c:url>         <a href="javascript:popUp( '<c:out value='${url}'/>' );">         Summary As PopUp</a>      </body> </html>

After you've created these directories and files, your application's file structure should look something like Figure 14-6.

Figure 14-6. Directory structure of a Struts-SiteMesh application


Once you've got all of this in place, you can build and deploy your application. Figure 14-7 shows the main page now decorated by SiteMesh.

Figure 14-7. Struts-generated JSP decorated using SiteMesh


The pop-up window displayed when you click on the "Summary As PopUp" link is shown in Figure 14-8.

Figure 14-8. Pop-up browser window generated by SiteMesh


See Also

You'll find a good tutorial on using SiteMesh with Struts in one of Rick Reumann's "Struttin' with Struts" lessons at http://www.reumann.net/struts/lessons/sitemesh/rr_sitemesh_example.jsp.

Will Iverson has written a good SiteMesh introduction available at http://today.java.net/pub/a/today/2004/03/11/sitemesh.html.



    Jakarta Struts Cookbook
    Jakarta Struts Cookbook
    ISBN: 059600771X
    EAN: 2147483647
    Year: 2005
    Pages: 200

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