blob: 904812f6c1eab7677aece3ec428c0984e6f24ff5 [file] [log] [blame]
<html>
<head>
<title>Velocity - Velocity Tools - Layout Servlet</title>
<meta name="author" value="Nathan Bubna"/>
</head>
<body bgcolor="#ffffff" text="#000000" link="#525D76"
alink="#525D76" vlink="#525D76">
<table border="0" width="100%" cellspacing="4">
<tr><td colspan="2">
<a href="http://jakarta.apache.org/">
<img src="http://jakarta.apache.org/images/jakarta-logo.gif"
align="left" alt="The Jakarta Project" border="0"/>
</a>
<a href="index.html">
<img src="../images/velocityview.png" align="right" alt="< Tools - View >" border="0"/>
</a>
</td></tr>
<tr>
<td colspan="2">
<hr noshade="" size="1"/>
</td>
</tr>
<tr>
<td width="20%" valign="top" nowrap="true">
<p><strong><a href="../index.html">Velocity Tools</a></strong></p>
<p>
<strong>VelocityView</strong>
</p>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="../index.html#Download">Download</a></li>
<li><a href="index.html#Installation">Installation</a></li>
<li><a href="index.html#VelocityLayoutServlet">LayoutServlet</a></li>
<li><a href="index.html#Examples">Examples</a></li>
<li><a href="../javadoc/index.html">Javadoc</a></li>
</ul>
<p>
<strong>VelocityView Tools</strong>
</p>
<ul>
<li><a href="../javadoc/org/apache/velocity/tools/view/tools/AbstractPagerTool.html">AbstractPagerTool</a></li>
<li><a href="../javadoc/org/apache/velocity/tools/view/tools/AbstractSearchTool.html">AbstractSearchTool</a></li>
<li><a href="../javadoc/org/apache/velocity/tools/view/tools/BrowserSnifferTool.html">BrowserSnifferTool</a></li>
<li><a href="../javadoc/org/apache/velocity/tools/view/tools/ContextTool.html">ContextTool</a></li>
<li><a href="../javadoc/org/apache/velocity/tools/view/tools/CookieTool.html">CookieTool</a></li>
<li><a href="ImportTool.html">ImportTool</a></li>
<li><a href="../javadoc/org/apache/velocity/tools/view/tools/LinkTool.html">LinkTool</a></li>
<li><a href="../javadoc/org/apache/velocity/tools/view/tools/ParameterParser.html">ParameterParser</a></li>
<li><a href="ViewRenderTool.html">ViewRenderTool</a></li>
<li><a href="../javadoc/org/apache/velocity/tools/view/tools/ViewResourceTool.html">ViewResourceTool</a></li>
</ul>
<p>
<strong>Other Subprojects</strong>
</p>
<ul>
<li><a href="../generic/">GenericTools</a></li>
<li><a href="../struts/">VelocityStruts</a></li>
</ul>
<p>
</p>
</td>
<!-- RIGHT SIDE MAIN BODY -->
<td colspan="1" valign="top" align="left">
<table border="0" cellspacing="0" cellpadding="2" width="100%">
<tr>
<td colspan="2" bgcolor="#525D76">
<font color="#ffffff" face="arial,helvetica.sanserif">
<a name="VelocityLayoutServlet (VLS) Overview">
<strong>VelocityLayoutServlet (VLS) Overview</strong></a></font>
</td>
</tr>
<tr>
<td NOWRAP> &nbsp; &nbsp; &nbsp; &nbsp; </td>
<td>
<p>
This is an extension to the basic VelocityViewServlet. It provides
a simple layout control and customizable error screens for Velocity
Tools based projects. Velocity Tools is distributed with an example
app demonstrating the use of this servlet.
</p>
</td>
</tr>
</table>
<table border="0" cellspacing="0" cellpadding="2" width="100%">
<tr>
<td colspan="2" bgcolor="#525D76">
<font color="#ffffff" face="arial,helvetica.sanserif">
<a name="Installation">
<strong>Installation</strong></a></font>
</td>
</tr>
<tr>
<td NOWRAP> &nbsp; &nbsp; &nbsp; &nbsp; </td>
<td>
<p>
Since this class is an extension of the VelocityViewServlet (VVS),
to use it simply change the servlet-class value of the web.xml entry
to the following class:</p>
<p>
<a href="../javadoc/org/apache/velocity/tools/view/servlet/VelocityLayoutServlet.html">org.apache.velocity.tools.view.servlet.VelocityLayoutServlet</a>
</p>
<table border="0" cellspacing="0" cellpadding="2" width="100%">
<tr>
<td colspan="2" bgcolor="#828DA6">
<font color="#ffffff" face="arial,helvetica.sanserif">
<a name="Configuration Settings">
<strong>Configuration Settings</strong></a></font>
</td>
</tr>
<tr>
<td NOWRAP> &nbsp; &nbsp; &nbsp; &nbsp; </td>
<td>
<p>Three settings can be added to velocity.properties to control
the VLS, or the following default values will be used:</p>
<table width="100%" cellpadding="1" cellspacing="0" border="0"><tr><td bgcolor="#000000">
<table width="100%" cellpadding="5" cellspacing="0" border="0"><tr><td bgcolor="#FFFFFF">
<pre><sourcecode># Filepath for error template,
# relative to web application root directory
tools.view.servlet.error.template = Error.vm
# Directory for layout templates,
# relative to web application root directory
tools.view.servlet.layout.directory = layout/
# Filepath of the default layout template
# relative to the layout directory
# NOT relative to the root directory of the webapp!
tools.view.servlet.layout.default.template = Default.vm</sourcecode></pre>
</td></tr></table>
</td></tr></table>
</td>
</tr>
</table>
</td>
</tr>
</table>
<table border="0" cellspacing="0" cellpadding="2" width="100%">
<tr>
<td colspan="2" bgcolor="#525D76">
<font color="#ffffff" face="arial,helvetica.sanserif">
<a name="Layouts">
<strong>Layouts</strong></a></font>
</td>
</tr>
<tr>
<td NOWRAP> &nbsp; &nbsp; &nbsp; &nbsp; </td>
<td>
<p>
Now, in your layout templates, the only thing you really need is the
screen content reference. So an acceptable layout template could be:</p>
<p>
<sourcecode>
$screen_content
</sourcecode>
</p>
<p>
...but that would make this whole thing an idiotic waste of time.
At the least, you'll probably want to do something along these lines:
</p>
<table width="100%" cellpadding="1" cellspacing="0" border="0"><tr><td bgcolor="#000000">
<table width="100%" cellpadding="5" cellspacing="0" border="0"><tr><td bgcolor="#FFFFFF">
<pre><sourcecode>&lt;html&gt;
&lt;head&gt;
&lt;title&gt;$!page_title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
$screen_content
&lt;/body&gt;
&lt;/html&gt;
</sourcecode></pre>
</td></tr></table>
</td></tr></table>
<p>
This saves you the trouble of doing the basic &lt;html&gt;,&lt;head&gt;, and &lt;body&gt;
tags in every single screen. That's the point of layouts: to save effort
and eliminate redundancy. Note that this still lets the inner screen
control the title of the page. This works because the layout template
is blessed by the VLS with access to the same context as the screen *after*
the screen is done with it. Just do a #set( $page_title = "Hello" ) in the
screen.
</p>
<br clear="all"/>
</td>
</tr>
</table>
<table border="0" cellspacing="0" cellpadding="2" width="100%">
<tr>
<td colspan="2" bgcolor="#525D76">
<font color="#ffffff" face="arial,helvetica.sanserif">
<a name="Alternative Layouts">
<strong>Alternative Layouts</strong></a></font>
</td>
</tr>
<tr>
<td NOWRAP> &nbsp; &nbsp; &nbsp; &nbsp; </td>
<td>
<p>VLS provides two ways to specify an alternate
template for a requested page:</p>
<p><b>1. Specify the layout in the request parameters</b></p>
<p>
Just add the query string "layout=MyOtherLayout.vm" to any request params
and the VLS will find it and render your screen within that layout instead
of the default layout. It don't matter how you get the layout param into
the query data, only that it's there. If you're using the struts tools, the
most common will likely be:
</p>
<p>
&lt;a href="$link.setRelative('MyScreen.vm').addQueryData('layout','MyOtherLayout.vm')"&gt;
</p>
<p>
but form post data will work just as well.
</p>
<p><b>2. Specify the layout in the requested screen.</b></p>
<p>
In the requested screen, put a line like this:
<br clear="all"/>
#set( $layout = "MyOtherLayout.vm" )
</p>
<p>
This will direct the VLS to use "MyOtherLayout.vm" instead of
"Default.vm". <i>Setting the layout in this fashion will
override any layout set by the request parameters.</i>
</p>
<br clear="all"/>
</td>
</tr>
</table>
<table border="0" cellspacing="0" cellpadding="2" width="100%">
<tr>
<td colspan="2" bgcolor="#525D76">
<font color="#ffffff" face="arial,helvetica.sanserif">
<a name="'Navigations', 'Tiles', and How">
<strong>'Navigations', 'Tiles', and How</strong></a></font>
</td>
</tr>
<tr>
<td NOWRAP> &nbsp; &nbsp; &nbsp; &nbsp; </td>
<td>
<p>Those of you who are (or were) Turbine or Struts users will probably want to
do more than just set the layout and screen content. You want to include
arbitrary "tiles" or "navigations", right? Well, thanks to Velocity's built-in
<code>#parse</code> directive, this is easy.</p>
<p>First, create your "tile" as a separate template file like:</p>
<table width="100%" cellpadding="1" cellspacing="0" border="0"><tr><td bgcolor="#000000">
<table width="100%" cellpadding="5" cellspacing="0" border="0"><tr><td bgcolor="#FFFFFF">
<pre><sourcecode>&lt;div id="footer"&gt;I made this!&lt;/div&gt;</sourcecode></pre>
</td></tr></table>
</td></tr></table>
<p>For creativity's sake, we'll pretend this code is in a file named "Footer.vm"
that is located in the root of my webapp like my other non-layout templates.</p>
<table width="100%" cellpadding="1" cellspacing="0" border="0"><tr><td bgcolor="#000000">
<table width="100%" cellpadding="5" cellspacing="0" border="0"><tr><td bgcolor="#FFFFFF">
<pre><sourcecode>
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;$!page_title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
$screen_content
#parse('Footer.vm')
&lt;/body&gt;
&lt;/html&gt;
</sourcecode></pre>
</td></tr></table>
</td></tr></table>
<p>Easy, eh?</p>
<p>Now, what if you have a lot of different "footer" files and you want your screen
to decide which one will be used? No problem! Do something like this:</p>
<table width="100%" cellpadding="1" cellspacing="0" border="0"><tr><td bgcolor="#000000">
<table width="100%" cellpadding="5" cellspacing="0" border="0"><tr><td bgcolor="#FFFFFF">
<pre><sourcecode>
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;$!page_title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
$screen_content
#parse( $screen_footer )
&lt;/body&gt;
&lt;/html&gt;
</sourcecode></pre>
</td></tr></table>
</td></tr></table>
<p>and in your screen, just do
<code>#set( $screen_footer = 'FooFooter.vm' ).</code></p>
<p>Remember, your #parsed footer template will have access to the same
velocity context as your layout, which gets the screen's context
once the screen is done with it. This lets you set variables for
the layout and footer to use from your screens.</p>
<br clear="all"/>
</td>
</tr>
</table>
<table border="0" cellspacing="0" cellpadding="2" width="100%">
<tr>
<td colspan="2" bgcolor="#525D76">
<font color="#ffffff" face="arial,helvetica.sanserif">
<a name="Error Screen">
<strong>Error Screen</strong></a></font>
</td>
</tr>
<tr>
<td NOWRAP> &nbsp; &nbsp; &nbsp; &nbsp; </td>
<td>
<p>Ok, the idea here is pretty simple. If an uncaught exception or error is thrown
at some point during the processing of your screen and layout, the error() method
of the VLS is called. This overrides the default error() method of the VelocityViewServlet
to render a template instead of hardcoded html.
</p>
<p>This error screen will be rendered within a layout under the same rules as any other
screen, and will have the following values placed in its context to help you debug
the error:
</p>
<br clear="all"/>
<table>
<tr>
<td bgcolor="#039acc" colspan="" rowspan="" valign="top" align="left">
<font color="#000000" size="-1" face="arial,helvetica,sanserif">
Key available to Template
</font>
</td>
<td bgcolor="#039acc" colspan="" rowspan="" valign="top" align="left">
<font color="#000000" size="-1" face="arial,helvetica,sanserif">
Value
</font>
</td>
</tr>
<tr>
<td bgcolor="#a0ddf0" colspan="" rowspan="" valign="top" align="left">
<font color="#000000" size="-1" face="arial,helvetica,sanserif">
$error_cause
</font>
</td>
<td bgcolor="#a0ddf0" colspan="" rowspan="" valign="top" align="left">
<font color="#000000" size="-1" face="arial,helvetica,sanserif">
java.lang.Throwable that was thrown
</font>
</td>
</tr>
<tr>
<td bgcolor="#a0ddf0" colspan="" rowspan="" valign="top" align="left">
<font color="#000000" size="-1" face="arial,helvetica,sanserif">
$stack_trace
</font>
</td>
<td bgcolor="#a0ddf0" colspan="" rowspan="" valign="top" align="left">
<font color="#000000" size="-1" face="arial,helvetica,sanserif">
captured output of $error_cause.printStackTrace()
</font>
</td>
</tr>
</table>
<p>In the event that a MethodInvocationException is behind the calling of error(),
the root cause is extracted from it and dealt with as described above. But, since
template reference behavior is partly at fault here, the VLS will also add the
MethodInvocationException itself to the context as $invocation_exception. This
allows you to discover the reference and method call that triggered the root cause.
To get those, do something like this in your error template:
</p>
<table width="100%" cellpadding="1" cellspacing="0" border="0"><tr><td bgcolor="#000000">
<table width="100%" cellpadding="5" cellspacing="0" border="0"><tr><td bgcolor="#FFFFFF">
<pre><sourcecode>
#if( $invocation_exception )
oh joy! it's a MethodInvocationException!
Message: $invocation_exception.message
Reference name: $invocation_exception.referenceName
Method name: $invocation_exception.methodName
#end</sourcecode></pre>
</td></tr></table>
</td></tr></table>
<br clear="all"/>
</td>
</tr>
</table>
</td>
</tr>
<!-- FOOTER SEPARATOR -->
<tr>
<td colspan="2">
<hr noshade="" size="1"/>
</td>
</tr>
<!-- PAGE FOOTER -->
<tr><td colspan="2">
<div align="center"><font color="#525D76" size="-1"><em>
Copyright &#169; 1999-2003, Apache Software Foundation
</em></font></div>
</td></tr>
</table>
</body>
</html>