<?xml version="1.0"?> | |
<document> | |
<properties> | |
<title>The Velocity JSP Tag Library</title> | |
<author email="geirm@apache.org">Geir Magnusson Jr.</author> | |
</properties> | |
<body> | |
<section name="Contents"> | |
<p> | |
<ol> | |
<li> | |
<a href="#So You Have To Use JSP...">So You Have To Use JSP...</a> | |
<ul> | |
<li> | |
<a href="#What Are The Advantages">What Are The Advantages?</a> | |
</li> | |
</ul> | |
</li> | |
<li> | |
<a href="#Using The Velocity Taglib">Using The Velocity Taglib</a> | |
<ul> | |
<li> | |
<a href="#Automatic Scope Access">Automatic Scope Access</a> | |
</li> | |
<li> | |
<a href="#Strict Scope Access">Strict Scope Access</a> | |
</li> | |
</ul> | |
</li> | |
<li> | |
<a href="#Building The Velocity Taglib">Building The Velocity Taglib</a> | |
<ul> | |
<li> | |
<a href="#JJAR build">Build Using JJAR</a> | |
</li> | |
<li> | |
<a href="#nonJJAR build">Non-JJAR Traditional Build</a> | |
</li> | |
</ul> | |
</li> | |
<li> | |
<a href="#Configuration">Configuration</a> | |
</li> | |
</ol> | |
</p> | |
</section> | |
<section name="So You Have To Use JSP..."> | |
<p> | |
Sometimes it appears you don't have a choice - technology decisions are | |
made based on all sorts of factors, ranging from network externalities | |
("They're using it - I should too...") to legacy considerations | |
("They used it - I have to..."). | |
</p> | |
<p> | |
In the event where the usage of JSP is mandatory, we offer a JSP tag library that lets | |
you take advantage of the simple control directives and powerful binding to the | |
Java object model offered by Velocity. Using Velocity in your JSPs is as | |
simple as : | |
</p> | |
<source><![CDATA[ | |
<%@ taglib uri="/WEB-INF/veltag.tld" prefix="vel" %> | |
<html> | |
<head> | |
<title> Velocity! </title> | |
</head> | |
<jsp:useBean id="mybean" class="GeirBean" /> | |
<body> | |
<vel:velocity strictaccess="true"> | |
#set($mybean = $scopetool.getPageScope("mybean")) | |
#if(true) | |
this is true! | |
#end | |
<br> | |
$mybean.string | |
<br> | |
#foreach($item in $mybean.array) | |
$item <br> | |
#end | |
</vel:velocity> | |
</body> | |
</html> | |
]]></source> | |
<p> | |
Not hard at all, is it? | |
</p> | |
<a name="What Are The Advantages"><strong>What Are The Advantages?</strong></a> | |
<p> | |
The first question asked when confronted with this subject is something | |
along the lines of "What advantage does this have over 'pure' Velocity?". | |
Generally, there are few reasons why one would take a Velocity-only | |
system, and convert it to a JSP system with Velocity embedded in the | |
JSP pages. The only reason that you might want to do this is to use | |
an existing JSP taglib that you want to use that you don't have the | |
source code for, or don't wish to dig out the core functional classes | |
of a taglib you do have the source for. Otherwise, you could just drop | |
those core classes in the Context, and access them directly from within | |
the Velocity template. | |
</p> | |
<p> | |
The advantages, then, are found in a JSP-centric environment, where an | |
existing application is already written in JSP and you wish to add or | |
maintain functionality. Some things that Velocity provides : | |
<ul> | |
<li> | |
Simple access to Java objects, without any need to create a taglib | |
shell. If it has public methods on a public interface, you can | |
drop it right into a scope and access directly (or use a tool to | |
create an instances of the class for you.) | |
</li> | |
<li> | |
Simple access to complicated Java objects. It's not clear how to | |
access an arbitrary call chain such as $foo.bar( $thing ).getIterator().hasNext() | |
</li> | |
<li> | |
Although this is a matter of personal taste, some people prefer the | |
control directives of Velocity ( #if(), #else(), #elseif(), #foreach() ) | |
to the various taglibs that offer the same functionality. | |
<i>De gustibus non est disputandum!</i>. | |
</li> | |
<li> | |
An easy bridge between complicated Java objects and JSP - for example | |
if you wished to dynamically choose/create an object at runtime, and | |
then poke into a scope for access in other parts of the JSP, you could | |
do that. | |
<pre> | |
<vel:velocity strictaccess="true"> | |
#set($reqbean = $scopetool.getRequestScope("beaninrequest")) | |
#set($newthing = $reqbean.getThing().makeBlue("azure")) | |
$request.getSession().setAttribute("bluething", $newthing) | |
</vel:velocity> | |
</pre> | |
Or something like that :) | |
</li> | |
<li> | |
If nothing else, there are always the Velocimacros. | |
</li> | |
</ul> | |
</p> | |
</section> | |
<section name="Using The Velocity Taglib"> | |
<p> | |
The biggest challenge in bringing together Velocity and JSP is the | |
'impedance matching' related to scope and bean access. 'Scope', | |
the fundamental storage mechanism in JSP, is a | |
concept that comes from the underlying servlet API, where data objects | |
are stored for later retrieval within the page, request, session or | |
application. Velocity organizes data in a non-hierachical mechanism | |
called the 'context', the expectation being that a controller servlet | |
or other non-view code will manage and organize the data accessable | |
to the template. | |
</p> | |
<p> | |
So to make data access in JSPs easy using the Velocity taglib, two | |
separate approaches are offered. These two approaches, automatic | |
access and strict access, allow two distinct ways of managing and | |
accessing data. These two ways can also be used together. | |
</p> | |
<a name="Automatic Scope Access"><strong>Automatic Scope Access</strong></a> | |
<p> | |
The first way, automatic access, is the most convenient. When an | |
object is referenced (via a VTL 'reference'), the scopes are searched | |
to find an object with the same id. The scopes are searched in the | |
order of : | |
<ol> | |
<li> page scope </li> | |
<li> request scope </li> | |
<li> session scope </li> | |
<li> application scope </li> | |
</ol> | |
Automatic scope access is enabled by default. To use | |
automatic scope access, just access the bean by name. For example : | |
</p> | |
<source><![CDATA[ | |
<!-- place a bean in page scope --> | |
<jsp:useBean id="mybean" class="GeirBean" /> | |
<vel:velocity> | |
<!-- just access by id - the context --> | |
<!-- will find it automatically --> | |
#foreach($item in $mybean.array) | |
$item <br> | |
#end | |
</vel:velocity> | |
]]></source> | |
<p> | |
While automatic scope access is the easier of the two methods, | |
integrating with existing applications might require using the | |
other access mode, strict scope access, or a combination of the | |
two. | |
</p> | |
<a name="Strict Scope Access"><strong>Strict Scope Access</strong></a> | |
<p> | |
The alternative (or addition to) Automatic Scope Access is something called | |
<i>Strict Scope Access</i>. Strict Scope Acccess means that the Velocity | |
Context won't search the scopes for you - you must retrieve objects directly | |
using ScopeTool that is provided for your use in the template. This is a | |
closer model to that of regular JSP, where the designer must be aware of | |
the scopes that objects are stored in. | |
</p> | |
<p> | |
For example, the following snippet of JSP shows how the scopetool is used to | |
access an object in the request scope, and add it to the Velocity context. | |
Note how the <code>strictaccess</code> property is set to true in the | |
<code><vel:velocity strictaccess="true"></code> tag. This tells | |
the Veltag taglib to not do any automatic scope searching. Note that you can | |
mix the two modes, leaving off (or setting to false) <code>strictaccess</code> | |
and also using the scopetool to eliminate any question about the source | |
of an object. | |
</p> | |
<source><![CDATA[ | |
<jsp:useBean id="beaninrequest" class="GeirBean" scope="request" /> | |
<vel:velocity strictaccess="true"> | |
#set($reqbean = $scopetool.getRequestScope("beaninrequest")) | |
$reqbean.string | |
<br> | |
#foreach($item in $reqbean.array) | |
$item <br> | |
#end | |
</vel:velocity> | |
]]></source> | |
<p> | |
Again, pretty straightforward. | |
</p> | |
</section> | |
<section name="Building The Velocity Taglib"> | |
<p> | |
To use the Velocity taglib, you need to build it, as it is not | |
yet included in the main Velocity jar. In the Jakarta tradition, | |
we made it very easy to build. The code for the project is | |
located in the contrib section of the distribution under | |
<code>/contrib/temporary/veltag</code>. It is under the | |
temporary directory as it is hoped this package will | |
be accepted by the | |
<a href="http://jakarta.apache.org/taglibs/">Jakarta Taglibs</a> | |
project. | |
</p> | |
<a name="JJAR build"><strong>The Easy, JJAR Way</strong></a> | |
<p> | |
The Veltag taglib can be built using a new, <b>experimental</b> | |
jar management tool called <em>JJAR</em> | |
(Jakarta Jar Archive & Repository) which makes finding and retrieving the | |
dependencies to build the taglib simple. | |
</p> | |
<p> | |
<i>Please note that JJAR is | |
currently a work in progress - while every effort will be made to ensure | |
that the JJAR-based build works, it may not always be so. In that case, | |
do it the regular way, listed below.</i> | |
</p> | |
<p> | |
To build with JJAR : | |
<ol> | |
<li> | |
<a href="http://jakarta.apache.org/ant/">Ant</a>, the fabulous | |
Jakarta build tool, must be installed. | |
</li> | |
<li> | |
Get the Velocity distribution from CVS or a nightly snapshot. | |
</li> | |
<li> | |
Change directory to the <code>/contrib/temporary/veltag</code> | |
directory in the Velocity distribution. | |
</li> | |
<li> | |
Type : | |
<pre> | |
$ ant getjars | |
</pre> | |
This will fetch JJAR and then use JJAR to fetch the dependencies du | |
jour for Veltag. | |
</li> | |
<li> | |
Type : | |
<pre> | |
$ant jar | |
</pre> | |
which will build the veltag-XX.jar (XX = current version). | |
</li> | |
</ol> | |
That's it. Pretty easy. | |
</p> | |
<a name="nonJJAR build"><strong>The JJAR-Is-A-Work-In-Progress Way</strong></a> | |
<p> | |
In the event the JJAR-based build is broken, or you just enjoy | |
schlepping around finding jars, do the following to build Veltag. | |
</p> | |
<p> | |
To build, you need the following : | |
<ul> | |
<li> | |
<a href="http://jakarta.apache.org/ant/">Ant</a>, the fabulous | |
Jakarta build tool, must be installed. | |
</li> | |
<li> | |
You will need a servlet API jar. We recommend you get it from | |
<a href="http://jakarta.apache.org/builds/jakarta-tomcat/release/v3.2.3/bin/">here</a> | |
for servlet 2.2 and | |
<a href="http://jakarta.apache.org/builds/jakarta-servletapi-4/nightly/">here</a> | |
for the unreleased servlet 2.3 API. Note - if you are a JSP user, you will have | |
one included with your servlet engine. | |
</li> | |
<li> | |
A velocity.jar. This can be found, of course, | |
<a href="http://jakarta.apache.org/velocity/">here</a>. | |
</li> | |
<li> | |
The build script expects to find the servlet and velocity jars in the | |
<code>/contrib/temporary/veltag/lib/</code> | |
directory. Modification | |
of the build script is easy if they are in another location. Look for | |
'servlet.home' and 'velocity.home' in the | |
<code>/contrib/temporary/veltag/build.xml</code> file. | |
</li> | |
<li> | |
Once the above is complete, cd into | |
<code>/contrib/temporary/veltag</code> in the Velocity | |
distribution and type 'ant'. The jar should build | |
for you. | |
</li> | |
</ul> | |
</p> | |
</section> | |
<section name="Configuration"> | |
<p> | |
Using the taglib is very straightforward. The following assumes | |
that you have setup a servlet container with JSP support, such as | |
<a href="http://jakarta.apache.org/tomcat/">Tomcat</a>, and know | |
enough to write and view a simple JSP page. Also, all directory | |
references are relative to the root of the veltag project, not | |
the Velocity distribution. | |
</p> | |
<p> | |
To test the Velocity Taglib : | |
<blockquote> | |
You need to copy the veltag-XX.jar to the | |
<code>WEB-INF/lib</code> directory of your webapp. (Where XX | |
is the current version number. | |
</blockquote> | |
<blockquote> | |
Take the example taglib descriptor, | |
<code> /examples/veltag.tld</code> and place in WEB-INF of your | |
webapp. | |
</blockquote> | |
<blockquote> | |
Finally, add | |
<pre> | |
<taglib> | |
<taglib-uri>http://jakarta.apache.org/taglibs/veltag-1.0</taglib-uri> | |
<taglib-location>/WEB-INF/veltag.tld</taglib-location> | |
</taglib> | |
</pre> | |
to your web.xml file, within the <webapp> section. | |
</blockquote> | |
If you wish to use the included example JSP, you will also need to compile | |
<code>examples/SimpleBean.java</code> and place the resulting | |
<code>SimpleBean.class</code> into the <code>WEB-INF/classes</code> | |
directory in your webapp. | |
</p> | |
<p> | |
After that, try the example JSP found in <code>examples/</code>. Drop it | |
into the root of your webapp and view it with your browser. Enjoy! | |
</p> | |
<p> | |
Please direct all comments, questions, fixes and contributions to | |
<a href="mailto:geirm@apache.org?SUBJECT=Veltag">Geir Magnusson Jr.</a> or the | |
Velocity user list. To subscribe to the Velocity lists, read | |
<a href="http://jakarta.apache.org/site/mail.html">this</a> and follow the | |
instructions at the end. | |
</p> | |
<p> | |
Please note that this code is not an official part of the Velocity | |
distribution. | |
</p> | |
</section> | |
</body> | |
</document> | |