Thursday, 9 May 2013

JSP SiteMesh

Why Sitemesh?

Before answering to this question, let me briefly describe what a layout framework is. For a web application it is very important to maintain a consistent look and feel all over the site. This is mainly achieved by having header, footer, navigation bar, message bar etc. There are many ways to tackle this.
  1. Use XSL Transformations : This has been widely used in earlier web applications. But it needs complex XSL files.
  2. Use a common CSS : Using a common CSS will give a common look and feel, but it is very difficult to maintain
  3. Use Tiles framework : Tiles allows easy integration with Struts framework, reuse of every component, it supports nesting, pattern inheritance, component reference etc. But the number of XMLs used will be increment based on the number of pages in your web app. Tiles uses JSP include which is not preferred as it needs to be in every page.
  4. Use Sitemesh : Sitemesh allows you to create plain HTML content that has no knowledge of how it will be decorated thereby achieving clean separation of presentation and content. It provides compatibility with all web frameworks, maintainability, filter based, a central configuration (even across web applications), patterns (applies decorator to defined patterns), nesting of decorators, fragments, tag attributes, separation from content, atomic pages,less coupling etc.

How to start ?

First you have to get sitemesh.jar.  You can have jstl.jar too in your classpath if you wish to use JSTL tags.

Elementary Configuration

Filter mapping in web.xml
 <filter>  
  <filter-name>sitemesh</filter-name>  
  <filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>  
 </filter>  
 <filter-mapping>  
  <filter-name>sitemesh</filter-name>  
  <url-pattern>/*</url-pattern>  
 </filter-mapping>  

Add decorator.xml to WEB-INF directory

 <?xml version="1.0" encoding="UTF-8"?>  
 <decorators defaultdir="/decorators">  
   <decorator name="my-theme" page="my-theme.jsp">  
     <pattern>/pages/*</pattern>  
   </decorator>  
 </decorators>  

my-theme.jsp is the template.
 <?xml version=”1.0″ encoding=”UTF-8″ ?>  
 <%@ taglib uri=”http://www.opensymphony.com/sitemesh/decorator” prefix=”decorator” %>  
 <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”  
 “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>  
 <html xmlns=”http://www.w3.org/1999/xhtml”>  
 <head>  
 <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″/>  
 <link href=”….”/>  
 <script src=”…..”></script>  
   <title><decorator:title default=”HELLO” /></title>  
   <decorator:head />  
 </head>  
 <body>  
 <div id=”page-content”>  
 <%@include file=”../include/navigation.jsp”%>  
 <%@include file=”../include/messagebar.jsp”%>  
 <decorator:body />  
 </div>  
   <div id=”footer”>  
 <p>Copyright (c) 2012. All rights reserved.</p>  
 </div>  
 <div>  
 Loading.. Please wait..  
 </div>  
 </body>  
 </html>  

That’s it!  Now all the pages having URL  /pages/* will be decorated using my-theme.jsp

 Advanced Configuration

Exclude

Suppose our decorator URI pattern includes several other files like JavaScript, CSS, images etc. We can have an exclude pattern as well in decorator.xml

  <!-- Excludes will be skipped by Sitemesh. -->  
  <excludes>  
   <pattern>*/nodecoration/*</pattern>  
   <pattern>*.css</pattern>  
   <pattern>*.js</pattern>  
  </excludes>  

Custom Decorator

You can also instruct your page to use a specific decorator instead of the one defined as per URI pattern. Use meta tag as follows for the same.
<meta name="decorator" content="decoratorName"/> 

Passing data to decorator

There are several ways to pass data into decorator from calling JSP/HTML.
1. Use meta tags
<meta name="param1" content="Parameter1 Value">
 2. Use content tag
<content tag="param2">Parameter2 Value</content>
param1 can be retrieved from decorator page in 2 ways.
1.  getProperty
<decorator:getProperty property="meta.param1"/>
or
<decorator:usePage id="pageobj" />  
<% String value1 = pageobj.getProperty("meta.param1"); %>
Similarly param2 can be retrieved as follows
<decorator:getProperty property="page.param2"/>
or
<decorator:usePage id="pageobj" />  
<% String value2 = pageobj.getProperty("page.param2"); %>

Decorator Tags

 <decorator:head />

Insert contents of original page’s HTML <head> tag.

 <decorator:body />

Insert contents of original page’s HTML <body> tag

<decorator:title default="..." ] />

Insert title of page being decorated.

<decorator:getProperty property="..." default="..." ] [writeEntireProperty="..." ]/> 

Insert property of original page, where property is the name of property to insert, writeEntireProperty (true/yes/1) will insert both attribute name and value.

<decorator:usePage id="..." />

Expose the Page object as a variable to the decorator JSP.

Page Tags

The page tags, are used to apply decorators to inline or external content from within the current page.

1. Page applyDecorator

<page:applyDecorator name="..." page="..." title="..." ] >    ..... </page:applyDecorator>
Apply a Decorator to specified content. The content can either be inline by specifying a body to the tag, or by using the result of another page by specifying the page attribute.
1. name (mandatory) : Name of the Decorator to apply to the included page.
2. page (optional) : Points to the external resource which should expose an entire page (e.g. another JSP file producing a valid page).
This attribute can be relative to the page it is being called from, or an absolute path from the context-root.
3. title (optional) : Override the title of the page available as Page.getTitle() or <decorator:title/> from within the Decorator.
This is identical to specifying <page:param name=”title”>…<page:param>.

2. Page Param

<page:param name="..."> ... </page:param>
Pass a parameter to a Decorator. This will override the value called from Page.getProperty() or <decorator:getProperty/>. This tag is only valid inside a <page:applyDecorator> tag.

References

No comments:

Post a Comment