Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3
Info
titleAbout SiteMesh

SiteMesh is a

Wiki Markup
h1. Overview [SiteMesh|http://www.opensymphony.com/sitemesh] is a

web-page

layout

and

decoration

framework

and

web

-

application

integration

framework

to

aid

in

creating

large

sites

consisting

of

many

pages

for

which

a

consistent

look/feel,

navigation

and

layout

scheme

is required.

The Sitemesh plugin

Excerpt

allows Sitemesh templates to access framework resources

.

The framework stores all its value stack information as request attributes, meaning that if you wish to display data that is on the stack (or even the ActionContext), you can do so by using the normal tag libraries that come with the framework. That's it!

Features

  • Can use Struts tags in Sitemesh decorator templates
  • Sitemesh decorators can be written in FreeMarker as well as Velocity and JSP

Usage

From 2.2+ the new com.opensymphony.sitemesh.webapp.SiteMeshFilter filter and Struts org.apache.struts2.dispatcher.ng.listener.StrutsListener context listener must be added to web.xml, like:

Code Block
xml
xml

<filter>
    <filter-name>sitemesh</filter-name>
    <filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
</filter> 
...
<listener>
    <listener-class>org.apache.struts2.dispatcher.ng.listener.StrutsListener</listener-class>
</listener> 

FreeMarker and Velocity Decorators

The plugin provides an extension of the SiteMesh Velocity and FreeMarker servlets. These servlets provide the standard variables and Struts Tags that you used to create views in your favourite template language.

FreeMarker

From 2.2+ the recommended way to use Freemarker with Sitemesh is through the org.apache.struts2.sitemesh.FreemarkerDecoratorServlet servlet, which can be configured like this in web.xml:

Code Block
xml
xml

<servlet>
    <servlet-name>sitemesh-freemarker</servlet-name>
    <servlet-class>org.apache.struts2.sitemesh.FreemarkerDecoratorServlet</servlet-class>
    <init-param>
 	<param-name>default_encoding</param-name>
 	<param-value>UTF-8</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet> 

<servlet-mapping>
    <servlet-name>sitemesh-freemarker</servlet-name>
    <url-pattern>*.ftl</url-pattern>
</servlet-mapping> 

Velocity

From 2.2+ the recommended way to use Velocity with Sitemesh is through the org.apache.struts2.sitemesh.VelocityDecoratorServlet servlet, which can be configured like this in web.xml:

Code Block
xml
xml

<servlet>
    <servlet-name>sitemesh-freemarker</servlet-name>
    <servlet-class>org.apache.struts2.sitemesh.VelocityDecoratorServlet</servlet-class>
    <init-param>
 	<param-name>default_encoding</param-name>
 	<param-value>UTF-8</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet> 

<servlet-mapping>
    <servlet-name>sitemesh-freemarker</servlet-name>
    <url-pattern>*.ftl</url-pattern>
</servlet-mapping> 

Full integration with SiteMesh 2 + Freemarker 2.4.2 + Velocity 1.3 , including Struts 2 Tags, ValueStack, and FreemarkerManager statics.

Such configuration is available as from Struts 2.2.0, please refer to WW-3296 for me details.

Code Block
xml
xml

    <filter>
        <filter-name>struts-prepare</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter</filter-class>
    </filter>

    <filter>
        <filter-name>sitemesh</filter-name>
        <filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
    </filter>

    <filter>
        <filter-name>struts-execute</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts-prepare</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter-mapping>
        <filter-name>sitemesh</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
    </filter-mapping>

    <filter-mapping>
        <filter-name>struts-execute</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>sitemesh-freemarker</servlet-name>
        <servlet-class>org.apache.struts2.sitemesh.FreemarkerDecoratorServlet</servlet-class>
        <init-param>
            <param-name>default_encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>sitemesh-freemarker</servlet-name>
        <url-pattern>*.ftl</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>JspSupportServlet</servlet-name>
        <servlet-class>org.apache.struts2.views.JspSupportServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <listener>
        <listener-class>org.apache.struts2.dispatcher.ng.listener.StrutsListener</listener-class>
    </listener>

Example

Here is an example of how to configure the filter chains in web.xml:

Code Block
xml
xml

<filter>
    <filter-name>struts-prepare</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter</filter-class>
</filter>

<filter>
    <filter-name>struts-execute< required.

Integrating WebWork with SiteMesh is amazingly simple: you don't have to do anything in fact. WebWork stores all its value stack information in the request attributes, meaning that if you wish to display data that is in the stack (or even the ActionContext) you can do so by using the normal tag libraries that come with WebWork. That's it!



h2. Passing data around

One thing to note is when you want to pass a value from a decorated page to a decorator using the *<ww:set>* tag, you need to specify a scope (request, session, application) if the decorated page is invoked directly (not a result of an action).  By default if no action has been executed and no scope was specified, the set value will only availlable from the same PageContext. Look [here|set] for more information.



h2. Localization

WebWork provides easy to use i18n functionality to SiteMesh decorators. Now using the *<ww:text/>* tag works seemlessly. In the event where you need to reference an i18n string, use the _id_ attribute as documented in the [Text] tag. An example of such situation is given below. 

Typically embedding i18n in to form elements would be done using the following:
{code:xml}
<ww:textfield label="%{getText('com.acme.login.text')}" name="login"/>
{code}

However, due to the way WebWork and SiteMesh work, you would need to seperate the above code in to two tags.

{code:xml}
<ww:text id="login" name="com.acme.login.text"/>

<ww:textfield label="#login" name="login"/>
{code}



h2. Custom Decorators

In WebWork's [Architecture], the standard filter-chain optionally starts with the *ActionContextCleanUp* filter, followed by other desired filters. Lastly, the *FilterDispatcher* handles the request, usually passing it on to the ActionMapper. 

{warning:title=Warning}
_If_ ActionContext access is required within the decorators, the *ActionContextCleanUp* filter _must_ be placed at the beginning of their filter-chain. This tells the FilterDispatcher when, exactly, to clean-up the request. Otherwise, the ActionContext may be removed before the decorator attempts to access it.
{warning}


h3. Velocity 

If you are using Velocity for your SiteMesh decorators, we recommend using the VelocityPageFilter. This is an extension of the SiteMesh PageFilter, which should be placed in the web.xml in between the *ActionContextCleanUp* and the *FilterDispatcher*. Now the Velocity decorators will have access to WebWork variables such as $stack and $request.

{code:xml|title:web.xml}
    <filter>
    	<filter-name>webwork-cleanup</filter-name>
    	<filter-class>comclass>org.opensymphonyapache.webworkstruts2.dispatcher.ng.filter.ActionContextCleanUp<StrutsExecuteFilter</filter-class>
    </filter>


<filter>
    <filter>
	<filter-name>sitemesh</filter-name>
	    <filter-class>com.opensymphony.webworksitemesh.sitemeshwebapp.VelocityPageFilter<SiteMeshFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>struts-prepare</filter-name>
    </filter><url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter><filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>webwork<name>struts-execute</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
    <filter<listener-class>comclass>org.opensymphonyapache.webworkstruts2.dispatcher.FilterDispatcher</filter-class>ng.listener.StrutsListener</listener-class>
</listener>

<servlet>
    <servlet-name>sitemesh-freemarker</servlet-name>
    </filter>
{code} 


h3. FreeMarker 

If you are using FreeMarker for your SiteMesh decorators, we recommend using the FreeMarkerPageFilter. This is an extension of the SiteMesh PageFilter, which should be placed in the web.xml in between the *ActionContextCleanUp* and the *FilterDispatcher*. Now the FreeMarker decorators will have access to WebWork variables such as ${stack} and ${request}.

{code:xml|title:web.xml}
    <filter>
    	<filter-name>webwork-cleanup<<servlet-class>org.apache.struts2.sitemesh.FreemarkerDecoratorServlet</servlet-class>
    <init-param>
        <param-name>default_encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet>
    <servlet-name>sitemesh-velocity</servlet-name>
    <servlet-class>org.apache.struts2.sitemesh.VelocityDecoratorServlet</servlet-class>
    <init-param>
        <param-name>default_encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>sitemesh-freemarker</servlet-name>
    <url-pattern>*.ftl</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>sitemesh-velocity</servlet-name>
    <url-pattern>*.vm</url-pattern>
</servlet-mapping>

Struts 2.1 web.xml filter chain example:

Code Block
xml
xml

<filter>
    <filter-name>struts-prepare</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter</filter-class>
</filter>

<filter>
    <filter-name>struts-execute</filter-name>
    	<filter-class>comclass>org.opensymphonyapache.webworkstruts2.dispatcher.ActionContextCleanUp<ng.filter.StrutsExecuteFilter</filter-class>
    </filter>

<filter>
    <filter>
	<filter-name>sitemesh</filter-name>
	    <filter-class>com.opensymphony.webworkmodule.sitemesh.FreeMarkerPageFilter<filter.PageFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>struts-prepare</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
</filter>/filter-mapping>

<filter-mapping>
    <filter-name>struts-execute</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

You do not need the struts2-sitmesh-plugin if you are using JSP for your decorators.
Here are the only only changes needed to web.xml

Code Block
xml
xml

<filter>
    <filter-name>struts2-prepare</filter-name>
    <filter-name>webwork<class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter</filter-name>class>
</filter>

<filter>
    <filter-name>sitemesh</filter-name>
    <filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class>.sitemesh.webapp.SiteMeshFilter</filter-class>
</filter>

<filter>
    <filter-name>struts2-execute</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>struts2-prepare</filter-name>
    </filter>
{code} 
<url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
</filter-mapping>

<filter-mapping>
    <filter-name>struts2-execute</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Settings

This plugin doesn't support any global settings.

Installation

This plugin can be installed by copying the plugin jar into your application's /WEB-INF/lib directory. No other files need to be copied or created.