Sitemesh 2: decorating from divs instead of body with the DivExtractingPageParser

By on

Struts 2.2.1 is using Sitemesh 2.4.2. Sitemesh is a very good but basic templating framework using the Decorator design pattern. Unfortunately Sitemesh 2 is discontinued and not really maintained anymore - even the latest release cannot be found on the old project website. The new Sitemesh website is targeting on version 3. I have refused to upgrade my Struts just to use some of the new features. Instead I tried to solve my little problem with a git clone of the Sitemesh 2 code.

The problem:

Usually you use the Sitemesh body tag to get out the whole content of the body which will then be decorated by the Decorator:

<decorator:body />

But if you have a two column design and want to avoid page includes and two jsps in the style of content1Sidebar.jsp and content1Mainpanel.jsp you are lost. What if you don't want a sidebar? Create an empty jsp file? Bah.

Instead you can try to decorate a jsp of that kind:

<div id="sidePanel">
     Some text
</div>
<div id="mainPanel">
       Something else
</div>

Decorating this is trivial - if you know the DivExtractingPageParser. If you have bootstrapped your Struts App with mvn archetype, you probably already have a sitemesh.xml. It contains a section like this:

<page-parsers>
   <parser content-type="text/html" class="com.opensymphony.module.sitemesh.parser.FastPageParser"/>
</page-parsers>

Well, on a sidenote: the FastPageParser is deprecated and should be replaced with the HTMLPageParser, if you want to use the body tag.

<parser content-type="text/html" class="com.opensymphony.module.sitemesh.parser.HTMLPageParser"/>

But we want something else - add the DivExtractingPageParser:

<page-parsers>
  <parser
    content-type="text/html"
    class="com.opensymphony.module.sitemesh.multipass.DivExtractingPageParser"/>
</page-parsers>

This parser extends the HTMLPageParser. It will draw the first level divs in your HTML and store it into properties. In this example you can use them in your Decorator (in my case the main.jsp) with:

<html>
....
<body>
...
<decorator:getProperty property="div.sidePanel"/>
...
<decorator:getProperty property="div.mainPanel"/>
...
</body>
</html>

And that's it. Don't forget to remove this tag:

<decorator:body />

And you'll need to create divs for every jsp file you want to decorate.

Tags: Apache Struts, Java, Open Source, Sitemesh