The easiest possible solution is to let each of your web applications create plain HTML content without knowing about how it is being decorated, and only then have something else choose and apply appropriate decorators. This is precisely what SiteMesh does.
In my experience, I’ve been able to easily solve these problems cleanly, easily, and elegantly using the open source servlet filter SiteMesh, which is hosted on java.net. Instead of requiring a new templating language, XSLT, or "porting" your pages to a new system, using SiteMesh often allows you to dramatically simplify your pages while still using ordinary HTML, JSP, servlets (including Struts), and other familiar technologies.
SiteMesh is an open source framework based on Java, J2EE, and XML. SiteMesh depends on filters, a cool feature introduced in the Servlet specification 2.3.
How does it work
SiteMesh implements a page filter, taking advantage of one of the lesser-known features of the servlet specification. Let’s imagine you have a simple JSP that returns the current date and time. Ordinarily, the request for the page comes in to the application server, the page is rendered, and then the results are returned to the web browser. SiteMesh, as a page filter, takes the page after it is rendered and performs additional processing before returning the document to the web browser. This change is most simply described as the additional step shown between Figure 1 and Figure 2.
Figure 2. SiteMesh Page Rendering
Sitemesh tag reference http://www.opensymphony.com/sitemesh/tags.html
Let’s look at a simple example of this. Consider the following simple JSP:
<meta name="author" content="email@example.com">
Hello World! <br />
<%= 1+1 %>
You’ll notice that the page has a title and a body (like any ordinary HTML page).
You’ll notice a tiny bit of JSP code — this will be rendered just as you would expect. Indeed, you can use any and all features that you would expect, and you link between the various JSP and other resources just as you might expect.
Now, let’s look at a simple SiteMesh "decorator" page. The following shows a JSP page, called by SiteMesh.
<%@ taglib uri="sitemesh-decorator"
My Site – <decorator:title default="Welcome!" />
<h1><decorator:title default="Welcome!" /></h1>
<a href="mailto:<decorator:getProperty property="meta.author"
Looking at the decorator, we can see a few interesting things. First, a SiteMesh taglib is introduced in the first line. This taglib includes everything required to work with the original page. You can see that we use two of the SiteMesh declared tags, <decorator:title> and <decorator:body>, which will read the associated content from the original page respectively (“Simple Document” for title and “Hello World! 2” for body) and display them in the re-rendered page. We’re making a few fairly radical changes to the page, including repeating the title both in the HEAD element as well as the BODY. We’re also adding a link to a printable version of the page.
Installation and Setup
Here are the steps to building the simple web application:
1 SiteMesh is based on filters, so we have to inform our web application about the SiteMesh filter. Adding the following lines to web.xml can do this:
Here we are telling the container that all requests to this web application should go through
PageFilter class is part of sitemesh-2.1.jar, which you can download from the SiteMesh downloads page. To stop applying Sitemesh feature, you can simply comment the code above.
2 Create a decorators.xml file in the WEB-INF folder like this:
<!-- Decorator for pages which need Sidemenu -->
<decorator name="sidemenu" page="sidemenu.jsp">
<!-- Decorator for pages which need header and footer -->
<decorator name="headerfooter" page="headerfooter.jsp">
<decorator name="printable" page="printable.jsp"/>
The WEB-INF/decorators.xml file is used to bind a decorator name to a specific JSP decorator file. In this file, each
<decorator> element defines one decorator. The
name attribute is used to define a name for that decorator, while the
page attribute defines the JSP page that should be used for decorating. The
<pattern> child element defines when a particular decorator should be applied.
In our example web application, we want two decorators: headerfooter.jsp, to add a header and footer, and sidemenu.jsp, to add a header, a footer, and a side menu. We want to decorate the help page by adding a header and footer, so we add the /help.jsp path sub-element to headerfooter.jsp.
Besides, another feature has been employed in the sample above. Since the page have a printable=true parameter, the printable decorator will be applied.
One more advance tip for using meta tag with Sitemesh. You’ll notice that we use a default attribute in the getProperty tag — if no author is specified, we’ll just assume that it was written by the staff. If you decide to use this model for storing page metadata, you’ll want to work with your content developers and other team members to determine what tags you want to use and how you’ll be using them. At the simple end, you may want to use meta tags to describe things like the author and page timestamp. At the complex end, you may do things like standardize on an XML file to manage your site navigation and use a meta tag to pass the page’s node to the decorator.
As we’ve seen, SiteMesh provides for a powerful, easy-to-use, non-intrusive mechanism for applying page templates. It’s easy to envision a wide range of possible uses. For example, you might define a decorator that emits extra debugging information about the page, as determined by the browser (this is especially powerful when combined with a web browser that lets you set an arbitrary user-agent). You might define a decorator with a stripped-down XML output, allowing for easier automated testing. You can even use the decorator to grab content from other pages, for example, to simple portal-like capability.
Once you’ve gotten comfortable with sitemesh-blank.war, I’d suggest looking at sitemesh-example.war for more features and ideas.
Regardless of how you use SiteMesh, I’ve found that it lets me centralize a tremendous amount of code, moving it out of my presentation layer and into my decorators, without having to learn a new programming language or templating system.
Oh, and as a final note for those of you still interested in building web pages in assembly, check out home.worldonline.dk/viksoe/asmil.htm.