My Tiles to SiteMesh Migration
I spent a few hours last night replacing Tiles with SiteMesh in AppFuse. I had the Struts version done in 2 hours, and most of the Spring version done in an additional hour. Then I spent another 3 hours today twiddling with things and getting it just right. During this process, I discovered a few things I thought I'd share. Keep in mind that I'm pretty much a SiteMesh rookie. Hopefully, implementing and using it in AppFuse will help me to fully understand its power.
- SiteMesh lacks injection. Tiles allows you to inject JSP fragments into your base layout on a per-page basis. I didn't use this feature much, but I did use it to determine which menu should show up on what pages. For example, the login page would get a "projects used" menu, the signup page wouldn't have a menu, and all other pages would get the standard site menu. With SiteMesh, all of this seems to be done best with JSP includes and some <c:if> logic in your decorator. I ended up using
<c:import>
in mylogin.jsp
for the login menu, importing nothing for signup, and using<c:if>
statements in my decorator to see if the user was logged in. If they were, then I import the site menu and its necessary scripts and styles. In the end, this worked fine and it's probably easier for new AppFuse users to understand - so that's a good thing. - Injecting scripts and stylesheets. With Tiles, I was able to easily control which scripts and stylesheets were shown on each page. With SiteMesh, this is pretty easy to do by putting them in the <head> element of your page. However, what I would've really liked to see is the ability to put these in an included JSP and have them end up in the <head> of the final document. I know it's virtually impossible, but it would be cool.
- Headings. Adding a <title> title element per-page works great using the <title> tag. However, if you want to add a heading (which I specify with an <h1> tag), you have to use a <content> tag. It would be cool if I could somehow use <h1> or <heading> in my page to indicate a heading. I ended up going with the following in each page to specify the title and heading:
<title><fmt:message key="mainMenu.title"/></title>
<content tag="heading"><fmt:message key="mainMenu.heading"/></content> - Injecting <body> ids. Using body ids to set styles on a per-page basis is a great way to control CSS. With Tiles, I set this as an attribute in
tiles-config.xml
and then grabbed/used it with the following JSTL code:<c:set var="bodyId" scope="request">
<tiles:getAsString name="body.id" ignore="true"/>
</c:set>
<body<c:if test="${not empty bodyId}"> id="<c:out value="${bodyId}"/>"</c:if>><body id="name">
. In fact, you don't even need to wrap your content with it, you can simpley do<body id="name"/>
. I'm grabbing and using this in my decorator with the following code. This works, but it would be cool if I could check for the existence of the attribute first - so I could eliminateid=""
when no body id is set.<body id="<decorator:getProperty property='body.id'/>">
- Inheritance. With Tiles, you could extend page definitions and override attributes. This feature seems to be completely lacking in SiteMesh. I don't know how you could implement it, but it would be nice to have something where you could specify the parent - for instance, to use the same <head> content.
- Error page decoration. SiteMesh seems to be incapable of decorating error pages (i.e. 404) in Tomcat 5.0.x (even if I add
<dispatcher>ERROR</dispatcher>
to the filter-mapping). A workaround is to use wrap the error page with a<page:applyDecorator>
tag. This works, but if you specify elements in <head>, they will end up in the body of page, rather than in the decorator's header. - SiteMesh simplifies. Switching from Tiles to SiteMesh allowed me to delete somewhere around 8 JSPs. AppFuse has 34 after committing everything. Most of these were JSPs that sat in the root folder and had a one-liner to pull in a Tiles definition. However, it also eliminated 11 JSPs from the Spring MVC install - allowing reduction of duplication. The Spring MVC install now has 17 JSPs.
So there you have it. AppFuse now uses SiteMesh instead of Tiles! I'm sure the implementation will get cleaner and more refined as more folks use it. I'm looking forward to deleting some chunks out of AppFuse's tutorials because SiteMesh makes page development so much easier. The hardest part of SiteMesh is setting up the infrastructure. Once you're got that done, you hardly ever touch it again.
Next task: WebWork integration.
Posted by Jason Carreira on August 22, 2004 at 06:05 PM MDT #
AppFuse + Spring + WebWork... now we're talking business...
One question though. I've been struggling around with WebWork tags working inside decorators. Am I missing something or this simply doesn't work?
I wasn't to get a simple "administrator.username" property to be shown in all my pages through the decorator. :-(
Posted by Alexandre Jacques on August 22, 2004 at 09:11 PM MDT #
Posted by Greg on August 22, 2004 at 09:18 PM MDT #
Posted by Matt Raible on August 22, 2004 at 09:57 PM MDT #
Posted by Charles Miller on August 22, 2004 at 10:26 PM MDT #
Mate,
Good post - great to see SiteMesh getting positive press. It is truly an awesome component.
Regarding your page chunking (headings etc) - you can already do this via the content blocks feature. Simply put <content tag="x">content here</content> into your page, and it will be available to your decorator as 'page.x'. Also useful because without decoration browsers will ignore the <content> tag, hence you can still preview your pages.
You can use this technique for all sorts of things, for example you could use it to aggregate stylesheets as you talked about using <content tag="stylesheet">...</content> and then in your decorator display all of the stylesheets in your head tag - or something like that.
I do realise that content tags are largely undocumented - we'll try to fix that! :)
FWIW My TSSS presentation on SiteMesh may be of use to people seeking an overview of SiteMesh, including details on 'how it works' under the hood and how we use it at Atlassian - I've uploaded it to the SiteMesh wiki here - http://wiki.opensymphony.com/display/SM/Index. Please do let me know if anything in it is confusing.
Cheers, Mike
PS If you need any help on the webwork integration, we've done that too! See the mailing list archives or email me with q's.
Posted by Mike Cannon-Brookes on August 23, 2004 at 12:44 AM MDT #
Posted by Matt Raible on August 23, 2004 at 01:47 AM MDT #
Posted by John Alchin on August 26, 2004 at 05:02 PM MDT #
Posted by Aks on August 27, 2004 at 12:17 PM MDT #
Posted by 2devnull on October 24, 2004 at 11:56 PM MDT #
Posted by 2devnull on October 25, 2004 at 02:47 AM MDT #
Posted by 2devnull on October 25, 2004 at 03:58 PM MDT #
I can inform you that when you add the following to your web.xml then error pages will be decorated (when using Tomcat 5.5.X):
Best Regards,
j3ns
(I know - this post is almost 2 years too late )
Posted by j3ns on June 22, 2006 at 09:43 AM MDT #
Posted by Emilio on December 30, 2006 at 12:31 PM MST #