<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | |
<!-- | |
Licensed to the Apache Software Foundation (ASF) under one | |
or more contributor license agreements. See the NOTICE file | |
distributed with this work for additional information | |
regarding copyright ownership. The ASF licenses this file | |
to you under the Apache License, Version 2.0 (the | |
"License"); you may not use this file except in compliance | |
with the License. You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, | |
software distributed under the License is distributed on an | |
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
KIND, either express or implied. See the License for the | |
specific language governing permissions and limitations | |
under the License. | |
--> | |
<!-- Content Stylesheet for Site --> | |
<!-- start the processing --> | |
<!-- ====================================================================== --> | |
<!-- Main Page Section --> | |
<!-- ====================================================================== --> | |
<html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> | |
<meta name="author" value="Velocity Documentation Team"> | |
<meta name="email" value="geirm@apache.org"> | |
<title>Velocity - Developer's Guide</title> | |
<style> | |
a:visited { color: blue; } | |
body { font-family: arial, helvetica, sans-serif; } | |
</style> | |
</head> | |
<body bgcolor="#ffffff" text="#000000" link="#525D76"> | |
<table border="0" width="100%" cellspacing="4"> | |
<tr><td bgcolor="#525D76"> | |
<font size="+2" color="#ffffff" face="arial,helvetica,sanserif"> | |
<strong>Velocity Developers Guide</strong> | |
</font> | |
</td></tr> | |
<tr><td colspan="2"> | |
<hr noshade="" size="1"/> | |
</td></tr> | |
<tr><td width="80%" align="left" valign="top"> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="Contents"><strong>Contents</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<p> | |
<ol> | |
<li> | |
<a href="developer-guide.html#Introduction">Introduction and Getting Started</a> | |
</li> | |
<li> | |
<a href="developer-guide.html#Resources">Resources</a> | |
</li> | |
<li> | |
<a href="developer-guide.html#How Velocity Works">How Velocity Works</a> | |
<ul> | |
<li><a href="developer-guide.html#The Fundamental Pattern">The Fundamental Pattern</a></li> | |
</ul> | |
</li> | |
<li> | |
<a href="developer-guide.html#To Singleton Or Not To Singleton...">To Singleton Or Not To Singleton...</a> | |
<ul> | |
<li><a href="developer-guide.html#Singleton">Singleton Model</a></li> | |
<li><a href="developer-guide.html#Separate">Separate Instance</a></li> | |
</ul> | |
</li> | |
<li> | |
<a href="developer-guide.html#The Context">The Context</a> | |
<ul> | |
<li><a href="developer-guide.html#The Basics">The Basics</a></li> | |
<li><a href="developer-guide.html#Support for Iterative Objects for #foreach()">Support for Iterative Objects for #foreach()</a></li> | |
<li><a href="developer-guide.html#Context Chaining">Context Chaining</a></li> | |
<li><a href="developer-guide.html#Objects Created in the Template">Objects Created by the Template</a></li> | |
<li><a href="developer-guide.html#Other Context Issues">Other Context Issues</a></li> | |
</ul> | |
</li> | |
<li> | |
<a href="developer-guide.html#Using Velocity In Servlets">Using Velocity in Servlets</a> | |
<ul> | |
<li><a href="developer-guide.html#Servlet Programming">Servlet Programming</a></li> | |
<li><a href="developer-guide.html#Deployment">Deployment</a></li> | |
</ul> | |
</li> | |
<li> | |
<a href="developer-guide.html#Using Velocity In General Applications">Using Velocity in General Applications</a> | |
<ul> | |
<li><a href="developer-guide.html#The Velocity Helper Class">The Velocity Helper Class</a></li> | |
<li><a href="developer-guide.html#Exceptions">Exceptions</a></li> | |
<li><a href="developer-guide.html#Miscellaneous Details">Miscellaneous Details</a></li> | |
</ul> | |
</li> | |
<li> | |
<a href="developer-guide.html#Application Attributes">Application Attributes</a> | |
</li> | |
<li> | |
<a href="developer-guide.html#EventCartridge and Event Handlers">EventCartridge and Event Handlers</a> | |
</li> | |
<li> | |
<a href="developer-guide.html#Velocity Configuration Keys and Values">Velocity Configuration Keys and Values</a> | |
</li> | |
<li> | |
<a href="developer-guide.html#Configuring the Log System">Configuring the Log System</a> | |
<ul> | |
<li> | |
<a href="developer-guide.html#Using Log4j With Existing Category">Using Log4j With Existing Category</a> | |
</li> | |
<li> | |
<a href="developer-guide.html#Simple Example of a Custom Logger">Simple Example of a Custom Logger</a> | |
</li> | |
</ul> | |
</li> | |
<li> | |
<a href="developer-guide.html#Configuring Resource Loaders">Configuring the Resource Loaders (template loaders)</a> | |
<ul> | |
<li> | |
<a href="developer-guide.html#Resource Loaders">Resource Loaders</a> | |
</li> | |
<li> | |
<a href="developer-guide.html#Configuration Examples">Configuration Examples</a> | |
</li> | |
<li> | |
<a href="developer-guide.html#Resource Manager and Cache">Pluggable Resource Manager and Resource Cache</a> | |
</li> | |
</ul> | |
</li> | |
<li> | |
<a href="developer-guide.html#Template Encoding for Internationalization">Template Encoding for Internationalization</a> | |
</li> | |
<li> | |
<a href="developer-guide.html#Velocity and XML">Velocity and XML</a> | |
</li> | |
<li> | |
<a href="developer-guide.html#FAQ (Frequently Asked Questions)">FAQ (Frequently Asked Questions)</a> | |
</li> | |
<li> | |
<a href="developer-guide.html#Summary">Summary</a> | |
</li> | |
<li> | |
<a href="developer-guide.html#Appendix 1 : Deploying the Example Servlet">Appendix 1 : Deploying the Example Servlet</a> | |
<ul> | |
<li> | |
<a href="developer-guide.html#TomcatExample">Jakarta Tomcat</a> | |
</li> | |
<li> | |
<a href="developer-guide.html#ResinExample">Caucho Technology's Resin</a> | |
</li> | |
<li> | |
<a href="developer-guide.html#WebLogic">BEA WebLogic</a> | |
</li> | |
</ul> | |
</li> | |
</ol> | |
</p> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="Introduction"><strong>Introduction</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<p> | |
Velocity is a Java-based template engine, a simple and powerful development tool | |
that allows you to easily create and render documents that format and present | |
your data. In this guide, we hope to give an overview of the basics of | |
development using Velocity, focusing on the two main areas for Velocity usage : | |
</p> | |
<ul> | |
<li>servlet-based WWW development</li> | |
<li>general application use</li> | |
</ul> | |
<p> | |
You will see that there is no real difference between these, other than we make | |
servlet development with Velocity very easy if you use our provided class | |
VelocityServlet as a base class for your servlet, and offer a utility class to | |
help with application development. | |
</p> | |
<p> | |
<strong>Getting Started</strong> | |
</p> | |
<p> | |
While this information is found elsewhere on the Velocity site and in the | |
documentation, it is included here for completeness. Getting Velocity running on | |
your computer is very easy. Note that all directory references are relative the | |
root of the Velocity distribution tree. | |
<ol> | |
<li> | |
Get the Velocity distribution. This is available as a release, nightly snapshot or | |
directly from the CVS code repository. Any are fine, although for the latest | |
features, the nightly snapshot is most likely the best way. For more | |
information, go <a href="index.html">here</a>. | |
</li> | |
<li> | |
If you don't have <a href="http://jakarta.apache.org/ant/">Jakarta Ant</a>, | |
the Java build tool already installed, please do so. It is required for | |
building Velocity, although not required for <i>using</i> Velocity. | |
</li> | |
<li> | |
Go to the <code>build</code> directory in the distribution. | |
</li> | |
<li> | |
Type <code>ant <build target></code> where <build target> | |
is one of: | |
<ul> | |
<li> | |
<b><code>jar</code></b> builds the complete Velocity jar in the | |
<code>bin</code> directory. This jar will be called 'velocity-X.jar', | |
where 'X' is the current version number. This jar does not include | |
necessary dependencies for Velocity. If you use this | |
target, you must get the Collections component jar from Jakarta Commons and add | |
to your CLASSPATH (or WEB-INF/lib). | |
If you wish to use the built-in logging or template conversion, | |
you must include the appropriate jars in your CLASSPATH or | |
webapp's WEB-INF/lib. | |
For convenience, you can use the <code>jar-dep</code> target to build | |
a jar with ORO, Logkit and Commons Collections included. | |
</li> | |
<li> | |
<b><code>jar-dep</code></b> builds the complete Velocity jar in | |
the <code>bin</code> directory, including necessary | |
support for logging from the | |
<a href="http://jakarta.apache.org/avalon/logkit/index.html">Jakarta | |
Avalon Logkit</a> package, critical configuration support from the | |
<a href="http://jakarta.apache.org/commons/">Jakarta Commons</a> | |
and the necesary support for WebMacro | |
template conversion using the | |
<a href="http://jakarta.apache.org/oro/index.html">Jakarta ORO</a> | |
package. | |
</li> | |
<li> | |
<b><code>jar-core</code></b> builds a slimmer Velocity jar in the | |
<code>bin</code> directory, called 'velocity-core-X.jar'. This jar | |
contains the core Velocity functionality, and doesn't include example | |
and utility things like Anakia, Texen or the VelocityServlet support | |
baseclass. It has the same external dependency requirements as the | |
regular <code>jar</code> target. | |
</li> | |
<li> | |
<b><code>jar-util</code></b> builds a utility Velocity jar in the | |
<code>bin</code> directory, called 'velocity-util-X.jar'. This jar | |
contains utility code, specifically Anakia, Texen, and the WebMacro | |
template conversion utility. It has the same external dependency requirements as the | |
regular <code>jar</code> target. | |
</li> | |
<li> | |
<b><code>jar-servlet</code></b> builds a utility Velocity jar in the | |
<code>bin</code> directory, called 'velocity-servlet-X.jar'. This jar | |
contains utility code for servlet programmers. It has the same external dependency requirements as the | |
regular <code>jar</code> target. | |
</li> | |
<li> | |
<b><code>jar-J2EE</code></b> builds a complete jar, like the 'jar' target, | |
that includes any components that require J2EE support. Currently, this | |
includes only org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader. | |
As usual, it is placed in the <code>bin</code> directory, called | |
'velocity-j2ee-X.jar'. NOTE : if you wish to use this build target, you | |
must place (or link) a copy of j2ee.jar into the build/lib directory. | |
We do not provide it as part of the distribution. A good source is | |
http://java.sun.com/. It has the same external dependency requirements as the | |
regular <code>jar</code> target. | |
</li> | |
<li> | |
<b><code>jar-J2EE-dep</code></b> build a complete jar with J2EE support | |
and includes logging support from the Jakarta Avalon Logkit and | |
regexp support fromt the Jakarta ORO package. See the notes on the | |
<code>jar-dep</code> target, above. | |
</li> | |
<li> | |
<b><code>examples</code></b> builds the example code in the example programs | |
found in the <code>examples</code> directory. This build target will | |
also build the forumdemo example project. | |
</li> | |
<li> | |
<b><code>forumdemo</code></b> builds the example webapplication in the | |
<code>examples/forumdemo</code> directory. | |
</li> | |
<li> | |
<b><code>docs</code></b> builds these docs in the <code>docs</code> directory | |
using Velocity's <a href="anakia.html">Anakia</a> XML transformation tool. | |
Allowing you to use | |
Velocity templates in place of stylesheets | |
- give it a try! <i>Note: This target requires that the jakarta-site2 project | |
is located as a peer directory to the jakarta-velocity distribution directory. | |
Please see the note in the build.xml file for this target for further information.</i> | |
</li> | |
<li> | |
<b><code>jar-src</code></b> bundles all the Velocity source code into a single | |
jar, placed in the <code>bin</code> directory. | |
</li> | |
<li> | |
<b><code>javadocs</code></b> builds the Javadoc class documentation in the | |
<code>docs/api</code> directory | |
</li> | |
<li> | |
<b><code>test</code></b> (after jar) will test Velocity against it's testbed | |
suite of test routines | |
</li> | |
<li> | |
<b><code>help</code></b> lists the build targets that are available. | |
</li> | |
</ul> | |
</li> | |
<li> | |
While not required, testing the build is a good idea. Use the | |
<code>test</code> target mentioned above. | |
</li> | |
<li> | |
That's it! Velocity is ready to be used. Put the jar into your classpath, or | |
into other appropriate places (such as the lib directory of your webapp if | |
using with servlets) | |
</li> | |
<li> | |
If you want to play with the examples, which is highly recommended when | |
getting started, use build the examples via | |
<code>ant examples</code>. | |
</li> | |
</ol> | |
</p> | |
<strong>Dependencies</strong> | |
<p> | |
Velocity uses elements of the Java 2 API such as collections, and therefore | |
building requires the Java 2 Standard Edition SDK (Software Development Kit). | |
To run Velocity, the Java 2 Standard Edition RTE (Run Time Environment) | |
is required (or you can use the SDK, of course). | |
</p> | |
<p> | |
Velocity also is dependent upon a few packages for general functionality. They | |
are included in the <code>build/lib</code> directory for convenience, but | |
the default build target (see above) does not include them. If you use the | |
default build target, you must add the dependencies to your classpath. | |
</p> | |
<ul> | |
<li> | |
<a href="http://jakarta.apache.org/commons/"> | |
<b>Jakarta Commons Collections</b></a> - required. | |
</li> | |
<li> | |
<a href="http://jakarta.apache.org/avalon/logkit/index.html"> | |
<b>Jakarta Avalon Logkit</b></a> - optional, but very common. | |
Needed if using the default file-based logging in Velocity. | |
</li> | |
<li> | |
<a href="http://jakarta.apache.org/oro/index.html"><b>Jakarta ORO</b></a> | |
- optional. Needed when using the | |
<code>org.apache.velocity.convert.WebMacro</code> template conversion | |
utility. | |
</li> | |
</ul> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="Resources"><strong>Resources</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<p> | |
There are quite a few resources and examples available to the programmer, and we | |
recommend that you look at our examples, documentation and even the source code. | |
Some great sources are : | |
</p> | |
<ul> | |
<li> | |
The user and developer community : join us via the | |
<a href="http://jakarta.apache.org/getinvolved/mail.html">mail-lists</a>. | |
</li> | |
<li> | |
Mail-list archives : <a href="http://www.mail-archive.com"> | |
http://www.mail-archive.com</a> is a good one. Type 'velocity' into the search | |
box to see both our -user and -dev archives. | |
</li> | |
<li> | |
source code : <code>src/java/...</code> : all the source code to the | |
Velocity project | |
</li> | |
<li> | |
application example 1 : <code>examples/app_example1</code> : a simple | |
example showing how to use Velocity in an application program. | |
</li> | |
<li> | |
application example 2 : <code>examples/app_example2</code> : a simple | |
example showing how to use Velocity in an application program using the | |
Velocity application utility class. | |
</li> | |
<li> | |
servlet example : <code>examples/servlet_example1</code> : a simple example | |
showing how to use Velocity in a servlet. | |
</li> | |
<li> | |
logger example : <code>examples/logger_example</code> : a simple example | |
showing how to create a custom logging class and register it with | |
Velocity to receive all log messages. | |
</li> | |
<li> | |
XML example : <code>examples/xmlapp_example</code> : a simple example | |
showing how to use JDOM to read and access XML document data from | |
within a Velocity template. It also includes a demonstration of | |
a recursive Velocimacro that walks the document tree. | |
</li> | |
<li> | |
event example : <code>examples/event_example</code> : An example that | |
demonstrates the use of the event handling API in Velocity 1.1 | |
</li> | |
<li> | |
Anakia application : <code>examples/anakia</code> : example application | |
showing how to use Velocity for creating stylesheet renderings of xml data | |
</li> | |
<li> | |
Forumdemo web app : <code>examples/forumdemo</code> : working example of a | |
simple servlet-based forum application | |
</li> | |
<li> | |
documentation : <code>docs</code> : all the generated documentation for the | |
Velocity project in html | |
</li> | |
<li> | |
API documentation : <code>docs/api</code> : the generated Javadoc | |
documentation for the Velocity project | |
</li> | |
<li> | |
templates : <code>test/templates</code> : a large collection of template | |
examples in our testbed directory, these are a great source of useage | |
examples of VTL, the Velocity Template Language | |
</li> | |
<li> | |
context example : <code>examples/context_example</code> : two examples | |
showing how the Velocity context can be extended. For advanced users. | |
</li> | |
</ul> | |
<p> | |
All directory references above are relative to the distribution root directory. | |
</p> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="How Velocity Works"><strong>How Velocity Works</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<p> | |
<a name="The Fundamental Pattern"><strong>'The Fundamental Pattern'</strong></a> | |
</p> | |
<p> | |
When using Velocity in an application program or in a servlet | |
(or anywhere, actually), you will generally do the following : | |
</p> | |
<ol> | |
<li>Initialize Velocity. This applies to both usage patterns for Velocity, | |
the Singleton as well as the 'separate runtime instance' (see more on this | |
below), and you only do this once.</li> | |
<li>Create a Context object (more on what that is later).</li> | |
<li>Add your data objects to the Context.</li> | |
<li>Choose a template.</li> | |
<li>'Merge' the template and your data to produce the ouput.</li> | |
</ol> | |
<p> | |
In code, using the singleton pattern via the | |
<code>org.apache.velocity.app.Velocity</code> class, | |
this looks like | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
import java.io.StringWriter; | |
import org.apache.velocity.VelocityContext; | |
import org.apache.velocity.Template; | |
import org.apache.velocity.app.Velocity; | |
import org.apache.velocity.exception.ResourceNotFoundException; | |
import org.apache.velocity.exception.ParseErrorException; | |
import org.apache.velocity.exception.MethodInvocationException; | |
Velocity.init(); | |
VelocityContext context = new VelocityContext(); | |
context.put( "name", new String("Velocity") ); | |
Template template = null; | |
try | |
{ | |
template = Velocity.getTemplate("mytemplate.vm"); | |
} | |
catch( ResourceNotFoundException rnfe ) | |
{ | |
// couldn't find the template | |
} | |
catch( ParseErrorException pee ) | |
{ | |
// syntax error : problem parsing the template | |
} | |
catch( MethodInvocationException mie ) | |
{ | |
// something invoked in the template | |
// threw an exception | |
} | |
catch( Exception e ) | |
{} | |
StringWriter sw = new StringWriter(); | |
template.merge( context, sw ); | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
That's the basic pattern. It is very simple, isn't it? This is generally what | |
happens when you use Velocity to render a template. You probably won't be | |
writing code exactly like this - we provide a few tools to help make it even | |
easier than this for both servlet and application programmers. | |
Later on in this guide, we will talk about using Velocity in both servlets | |
as well as general applications, and we discuss the tools we provide to make | |
things easier. In each case, though, the above sequence is what is happening | |
either explicitly, or behind the scenes. | |
</p> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="To Singleton Or Not To Singleton..."><strong>To Singleton Or Not To Singleton...</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<p> | |
As of Velocity 1.2 and later, developers now have two options | |
for using the Velocity engine, the singleton model and the separate instance | |
model. The same core Velocity code is used for both approaches, which are | |
provided to make Velocity easier to integrate into your Java application. | |
</p> | |
<p> | |
<a name="Singleton"><strong>Singleton Model</strong></a> | |
</p> | |
<p> | |
This is the legacy pattern, where there is only one instance of the Velocity | |
engine in the JVM (or web application, depending) that is shared by all. | |
This is very convenient as it | |
allows localized configuration and sharing of resources. For example, this | |
is a very appropriate model for use in a Servlet 2.2+ compliant web application | |
as each web application can have it's own instance of Velocity, allowing | |
that web application's servlet to share resources like templates, a logger, etc. | |
The singleton is accessable via the <code>org.apache.velocity.app.Velocity</code> | |
class, and and example of use : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
import org.apache.velocity.app.Velocity; | |
import org.apache.velocity.Template; | |
... | |
/* | |
* Configure the engine - as an example, we are using | |
* ourselves as the logger - see logging examples | |
*/ | |
Velocity.setProperty( Velocity.RUNTIME_LOG_LOGSYSTEM, this); | |
/* | |
* now initialize the engine | |
*/ | |
Velocity.init(); | |
... | |
Template t = Velocity.getTemplate("foo.vm"); | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
Please note that the Singleton model is used in the | |
<code>org.apache.velocity.servlet.VelocityServlet</code> base class, | |
a utility class provided with the distribution to make writing servlets | |
easier. While extending this class is the most common and convenient | |
way to write servlets using Velocity, you are free to not use this | |
class if you needs require something different. | |
</p> | |
<p> | |
<a name="Separate"><strong>Separate Instance</strong></a> | |
</p> | |
<p> | |
New in version 1.2, the separate instance allows you to create, configure | |
and use as many instances of Velocity as you wish in the same JVM | |
(or web application.) This | |
is useful when you wish to support separate configurations, such as template | |
directories, loggers, etc in the same application. To use separate | |
instances, use the <code>org.apache.velocity.app.VelocityEngine</code> | |
class. An example, which parallels the above singleton example, looks | |
like : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
import org.apache.velocity.app.VelocityEngine; | |
import org.apache.velocity.Template; | |
... | |
/* | |
* create a new instance of the engine | |
*/ | |
VelocityEngine ve = new VelocityEngine(); | |
/* | |
* configure the engine. In this case, we are using | |
* ourselves as a logger (see logging examples..) | |
*/ | |
ve.setProperty( VelocityEngine.RUNTIME_LOG_LOGSYSTEM, this); | |
/* | |
* initialize the engine | |
*/ | |
ve.init(); | |
... | |
Template t = ve.getTemplate("foo.vm"); | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
As you can see, this is very simple and straightforward. Except for some simple | |
syntax changes, using Velocity as a singleton or as separate instances requires | |
no changes to the high-level structure of your application or templates. | |
</p> | |
<p> | |
As a programmer, the classes you should use to interact with the Velocity | |
internals are the <code>org.apache.velocity.app.Velocity</code> class if | |
using the singleton model, or <code>org.apache.velocity.app.VelocityEngine</code> | |
if using the non-singleton model ('separate instance'). | |
</p> | |
<p> | |
At no time should an application use the internal <code>Runtime, RuntimeConstants, | |
RuntimeSingleton or RuntimeInstance</code> classes in the | |
<code>org.apache.velocity.runtime</code> package, as these are intended for | |
internal use only and may change over time. As mentioned above, | |
the classes you should use | |
are located in the <code>org.apache.velocity.app</code> package, and are the | |
<code>Velocity</code> and <code>VelocityEngine</code> classes. If anything is | |
missing or needed from those classes, do not hesitate to suggest changes - these | |
classes are intended for the application developer. | |
</p> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="The Context"><strong>The Context</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<a name="The Basics"><strong>The Basics</strong></a> | |
<p> | |
The concept of the 'context' is central to Velocity, and is a common technique | |
for moving a container of data around between parts of a system. The idea is | |
that the context is a 'carrier' of data between the Java layer (or you the | |
programmer) and the template layer ( or the designer ). You as the programmer | |
will gather objects of various types, whatever your application calls for, and | |
place them in the context. To the designer, these objects, and their methods | |
and properties, will become accessable via template elements called | |
<a href="vtl-reference-guide.html"> references</a>. Generally, you will work | |
with the designer to determine the data needs for the application. In a sense, | |
this will become an 'API' as you produce a data set for the designer to access | |
in the template. Therefore, in this phase of the development process it is | |
worth devoting some time and careful analysis. | |
</p> | |
<p> | |
While Velocity allows you to create your own context classes to support special | |
needs and techniques (like a context that accesses an LDAP server directly, for | |
example), a good basic implementation class called VelocityContext is provided | |
for you as part of the distribution. | |
</p> | |
<p> | |
VelocityContext is suitable for all general purpose needs, and we strongly | |
recommended that you use it. Only in exceptional and advanced cases will you | |
need to extend or create your own context implementation. | |
</p> | |
<p> | |
Using VelocityContext is as simple as using a normal Java Hashtable class. | |
While the interface contains other useful methods, the two main methods you | |
will use are | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
public Object put(String key, Object value); | |
public Object get(String key); | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
Please note that like a Hashtable, the value must be derived from | |
java.lang.Object, and must not be null. Fundamental types like int or float must | |
be wrapped in the appropriate wrapper classes. | |
</p> | |
<p> | |
That's really all there is to basic context operations. For more information, | |
see the API documentation included in the distribution. | |
</p> | |
<p> | |
<a name="Support for Iterative Objects for #foreach()"><strong>Support for Iterative Objects for | |
#foreach()</strong></a> | |
</p> | |
<p> | |
As a programmer, you have great freedom in the objects that you put into the | |
context. But as with most freedoms, this one comes with a little bit of | |
responsibility, so understand what Velocity supports, and any issues that may | |
arise. Velocity supports serveral types of collection types suitable for use | |
in the VTL <code>#foreach()</code> directive. | |
</p> | |
<ul> | |
<li> <code>Object [] </code> Regular object array, not much needs to be said | |
here. Velocity will internally wrap your array in a class that provides an | |
Iterator interface, but that shouldn't concern you as the programmer, or the | |
template author. | |
</li> | |
<li> <code>java.util.Collection</code> Velocity will use the | |
<code>iterator()</code> method to get an Iterator to use in the loop, | |
so if you are implementing a Collection interface on your object, please | |
ensure that <code>iterator()</code> returns a working Iterator. | |
</li> | |
<li> <code>java.util.Map </code> Here, Velocity depends upon the | |
<code>values()</code> method of the interface to get a <code>Collection</code> | |
interface, on which <code>iterator()</code> is called to retrieve an Iterator | |
for the loop. | |
</li> | |
<li> <code>java.util.Iterator</code> USE WITH CAUTION : This is currently | |
supported only provisionally - the issue of concern is the | |
'non-resettablity' of the Iterator. If a 'naked' Iterator is placed into | |
the context, and used in more than one #foreach(), subsequent #foreach() | |
blocks after the first will fail, as the Iterator doesn't reset. | |
</li> | |
<li> <code>java.util.Enumeration</code> USE WITH CAUTION : Like | |
<code>java.util.Iterator</code>, this is currently | |
supported only provisionally - the issue of concern is the | |
'non-resettablity' of the Enumeration. If a 'naked' Enumeration | |
is placed into the context, and used in more than one #foreach(), | |
subsequent #foreach() blocks after the first will fail, | |
as the Enumeration doesn't reset. | |
</li> | |
</ul> | |
<p> | |
In the case of the <code>Iterator</code> and <code>Enumeration</code>, it is | |
recommended that they are placed in the context only when it cannot be avoided, | |
and you should let Velocity find the appropriate reusable iterative interface when | |
that is sufficient and possible. | |
</p> | |
<p> | |
There are good reasons to use the <code>java.util.Iterator</code> interface | |
directly (large data sets via JDBC, for example), but if it can be | |
avoided, it might be better to use something else. By 'directly' , we meant | |
doing something like: | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
Vector v = new Vector(); | |
v.addElement("Hello"); | |
v.addElement("There"); | |
context.put("words", v.iterator() ); | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
where the Iterator itself is placed into the context. Instead, if you | |
simply did: | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
context.put("words", v ); | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
then all would be fine: Velocity would figure out that Vector implement | |
Collection (via List), and therefore will find the <code>iterator()</code> | |
method, and use that to get a 'fresh' Iterator for its use each time | |
it needs to. With just a plain Iterator (the first snippet above...), | |
once velocity has used it in a <code>#foreach()</code>, Velocity has | |
no way of getting a new one to use for the next <code>#foreach()</code> | |
it is used in. The result is no output from any subsequent | |
<code>#foreach()</code> blocks using that reference. | |
</p> | |
<p> | |
This above isn't meant to give the impression that iterating over | |
collections in Velocity is something that requires great care and | |
thought. Rather, the opposite is true, in general. Just be | |
careful when you place an Iterator into the context. | |
</p> | |
<a name="Context Chaining"><strong>Context Chaining</strong></a> | |
<p> | |
An innovative feature of Velocity's context design is the concept | |
of <i>context chaining</i>. Also sometimes referred to as | |
<i>context wrapping</i>, this advanced feature allows you to connect | |
separate contexts together in a manner that makes it appear as one | |
'contiguous' context to the template. | |
</p> | |
<p> | |
This is best illustrated by an example : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
VelocityContext context1 = new VelocityContext(); | |
context1.put("name","Velocity"); | |
context1.put("project", "Jakarta"); | |
context1.put("duplicate", "I am in context1"); | |
VelocityContext context2 = new VelocityContext( context1 ); | |
context2.put("lang", "Java" ); | |
context2.put("duplicate", "I am in context2"); | |
template.merge( context2, writer ); | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
In the code above, we have set up context2 such that it <i>chains</i> | |
context1. This means that in the template, you can access any of | |
the items that were put into either of the two VelocityContext objects, | |
as long as there is no duplication of the keys used to add objects. | |
If that is the case, as it is above for the key 'duplicate', the object | |
stored in the nearest context in the chain will be available. In this | |
example above, the object returned would | |
be the string "I am in context2". | |
</p> | |
<p> | |
Note that this duplication, or 'covering', of a context item does not in | |
any way harm or alter the covered object. So in the example above, the | |
string "I am in context1" is alive and well, still accessable via | |
context1.get("duplicate"). But in the example above, the value of the | |
reference '$duplicate' in the template would be 'I am in context2', | |
and the template has no access to the covered string 'I am in context1'. | |
</p> | |
<p> | |
Note also that you have to be careful when you are relying on the template | |
to add information to a context that you will examine later after the | |
rendering. The changes to the context via <code>#set()</code> statements | |
in a template will affect only the outer context. So make sure that you | |
don't discard the outer context, expecting the data from the template to | |
have been placed onto the inner one. | |
</p> | |
<p> | |
This feature has many uses, the most common so far is providing layered | |
data access and toolsets. | |
</p> | |
<p> | |
As mentioned before, the Velocity context mechanism is also extendable, | |
but beyond the current scope of this guide. If you are interested, | |
please see the classes in the package <code>org.apache.velocity.context</code> | |
to see how the provided contexts are put together. Futher, there are a few | |
examples in the <code>examples/context_example</code> directory in the | |
distribution which show alternate implementations, including [a goofy] one | |
that uses a database as the backing storage. | |
</p> | |
<p> | |
Please note that these examples are unsupported and are there for | |
demonstration/educational purposes only. | |
</p> | |
<a name="Objects Created in the Template"><strong>Objects Created in the | |
Template</strong></a> | |
<p> | |
There are two common situations where the Java code must deal with objects | |
created at runtime in the template : | |
</p> | |
<p> | |
When a template author calls a method of an object placed into | |
the context by Java code. | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
#set($myarr = ["a","b","c"] ) | |
$foo.bar( $myarr ) | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
When a template adds objects to the context, the Java code can access | |
those objects after the merge process is complete. | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
#set($myarr = ["a","b","c"] ) | |
#set( $foo = 1 ) | |
#set( $bar = "bar") | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
Dealing with these cases if very straighforward, as there are just a few | |
things to know: | |
</p> | |
<ul> | |
<li> | |
The VTL RangeOperator [ 1..10 ] and ObjectArray ["a","b"] are | |
<code>java.util.ArrayList</code> objects when placed in the context | |
or passed to methods. Therefore, your methods that are designed to | |
accept arrays created in the template should be written with this | |
in mind. | |
</li> | |
<li> | |
Numbers will be Integers in the context, and strings will be, of course, Strings. | |
</li> | |
<li> | |
Velocity will properly 'narrow' args to method calls, so calling | |
<code>setFoo( int i )</code> with an int placed into the | |
context via <code>#set()</code> will work fine. | |
</li> | |
</ul> | |
<a name="Other Context Issues"><strong>Other Context Issues</strong></a> | |
<p> | |
One of the features provided by the VelocityContext | |
(or any Context derived from AbstractContext) is | |
node specific introspection caching. Generally, you as a the developer | |
don't need to worry about this when using the VelocityContext | |
as your context. However, there is currently one | |
known usage pattern where you must be aware of this feature. | |
</p> | |
<p> | |
The VelocityContext will accumulate intropection information about the | |
syntax nodes in a template as it visits those nodes. So, in the following | |
situation: | |
</p> | |
<ul> | |
<li> | |
You are iterating over the same template using the same VelocityContext | |
object. | |
</li> | |
<li> | |
Template caching is off. | |
</li> | |
<li> | |
You request the Template from getTemplate() on each iteration. | |
</li> | |
</ul> | |
<p> | |
It is possible that your VelocityContext will appear to 'leak' memory | |
(it is really just gathering more introspection information.) What | |
happens is that it accumulates template node introspection information | |
for each template it visits, and as template caching is off, it appears | |
to the VelocityContext that it is visiting a new template each time. | |
Hence it gathers more introspection information and grows. It is highly | |
recommended that you do one or more of the following : | |
</p> | |
<ul> | |
<li>Create a new VelocityContext for each excursion | |
down through the template render process. This will prevent the accumulation | |
of introspection cache data. For the case where you want to reuse the | |
VelocityContext because it's populated with data or objects, | |
you can simply wrap the populated | |
VelocityContext in another, and the 'outer' one will accumulate the | |
introspection information, which you will just discard. Ex. | |
<code>VelocityContext useThis = new VelocityContext( populatedVC );</code> | |
This works because the outer context will store the introspection | |
cache data, and get any requested data from the inner context (as it is empty.) | |
Be careful though - if your template places data into the context and it's | |
expected that it will be used in the subsequent iterations, you will need to do | |
one of the other fixes, as any template #set() statements will be stored in | |
the outermost context. See the discussion in | |
<a href="developer-guide.html#Context Chaining">Context chaining</a> for more | |
information. | |
</li> | |
<li> | |
Turn on template caching. This will prevent the template from being re-parsed | |
on each iteration, resulting the the VelocityContext being able to not only | |
avoid adding to the introspection cache information, but be able to use it | |
resulting in a performance improvement. | |
</li> | |
<li> | |
Reuse the Template object for the duration of the loop iterations. | |
Then you won't be forcing Velocity, if the cache is turned off, to | |
reread and reparse the same template over and over, so the VelocityContext | |
won't gather new introspection information each time. | |
</li> | |
</ul> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="Using Velocity In Servlets"><strong>Using Velocity In Servlets</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<a name="Servlet Programming"><strong>Servlet Programming</strong></a> | |
<p> | |
The most common use of Velocity is in the area of Java Servlet programming | |
for the WWW. There are many reasons why Velocity is well suited for this | |
task, one of the primary ones is Velocity's enforcement of the | |
separation of the presentation (or view) layer from the | |
code layer. There are many resources on this subject, including | |
<a href="http://www.javaworld.com/javaworld/jw-12-1999/jw-12-ssj-jspmvc.html"> | |
this</a>. | |
</p> | |
<p> | |
The basic technique of using Velocity in a servlet environment is very simple. | |
In a nutshell, all you must do is extend the provided VelocityServlet base class | |
and implement a single method, <code>handleRequest()</code>. That's really all that is | |
required to use Velocity in your servlet development. | |
</p> | |
<p> | |
As of Velocity 1.1, there are two <code>handleRequest()</code> methods : | |
<br /> | |
<br /> | |
<i><code>public Template handleRequest( Context )</code></i> | |
<blockquote> | |
This is the older of the two methods. This method requires that you | |
return a valid Template object. If not valid, or <code>null</code>, | |
this is considered an error condition, and will result in the <a href="developer-guide.html#error()"><code>error()</code></a> error | |
handling method being called. You may override the | |
<code>error()</code> if you wish. If returning a <code>null</code> is | |
something you expect to do (for example, you will want to redirect | |
requests) it is recommended that you use the newer method, listed | |
next. | |
</blockquote> | |
<br /> | |
<i><code>public Template handleRequest( HttpServletRequest, HttpServletResponse, Context )</code></i> | |
<blockquote> | |
This is the newer of the two <code>handleRequest()</code> methods, | |
implemented in version 1.1. The difference with this method is that | |
the <code>HttpServletRequest</code> and | |
<code>HttpServletResponse</code> objects are passed to you as | |
arguments to the method, as well as in the <code>Context</code>. The | |
other difference is that this method can return <code>null</code> to | |
indicate that all processing has been handled by the method, and that | |
Velocity should do nothing further than call | |
<a href="developer-guide.html#requestCleanup()"><code>requestCleanup()</code></a>. | |
This is extremely useful is you wish to redirect the request, for | |
example. | |
</blockquote> | |
As always, please refer to the Javadoc API documentation for the definitive and | |
latest notes. | |
</p> | |
<p> | |
The following code is similar to the SampleServlet.java class included | |
in the distribution in the examples directory. | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
public class SampleServlet extends VelocityServlet | |
{ | |
public Template handleRequest( HttpServletRequest request, | |
HttpServletResponse response, | |
Context context ) | |
{ | |
String p1 = "Jakarta"; | |
String p2 = "Velocity"; | |
Vector vec = new Vector(); | |
vec.addElement( p1 ); | |
vec.addElement( p2 ); | |
context.put("list", vec ); | |
Template template = null; | |
try | |
{ | |
template = getTemplate("sample.vm"); | |
} | |
catch( ResourceNotFoundException rnfe ) | |
{ | |
// couldn't find the template | |
} | |
catch( ParseErrorException pee ) | |
{ | |
// syntax error : problem parsing the template | |
} | |
catch( Exception e ) | |
{} | |
return template; | |
} | |
} | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
Look familiar? With the exception of creating the context object, which is | |
done for you by the VelocityServlet base class, and the merge() step | |
which is also done for you by the VelocityServlet base class, it's identical | |
to the basic code pattern we mentioned at the beginning of this guide. | |
We take the context, add our application data, and return a template. | |
</p> | |
<p> | |
The default <code>Context</code> object that is passed into the | |
<code>handleRequest()</code> methods contains both the current | |
<code>HttpServletRequest</code> and <code>HttpServletResponse</code> | |
objects. They are placed in the context using the the constants | |
<code>VelocityServlet.REQUEST</code> (value = 'req') and | |
<code>VelocityServlet.RESPONSE</code> (value = 'res') | |
respectively. To access and use these objects in your Java code : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
public Template handleRequest( Context context ) | |
{ | |
HttpServletRequest request = (HttpServletRequest) context.get( REQUEST ); | |
HttpServletResponse response = (HttpServletResponse) context.get( RESPONSE ); | |
... | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
and in your templates: | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
#set($name = $req.getParameter('name') ) | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
For more advanced uses, the VelocityServlet base class allows you to override | |
parts of the handling of the request processing. The following methods may | |
be overridden : | |
<br /> | |
<br /> | |
<i><code> Properties loadConfiguration( ServletConfig )</code></i> | |
<blockquote> | |
Allows you to override the normal configuration mechanism and add or | |
alter the configuation properties. This is useful for overriding or | |
augmenting template and log paths, to set the absolute path into the | |
webapp root at runtime. | |
</blockquote> | |
<i><a name="createContext()"> | |
<code>Context createContext(HttpServletRequest, HttpServletResponse )</code></a></i> | |
<blockquote> | |
Allows you to create the Context object yourself. This allows more advanced | |
techniques, such as chaining or pre-loading with tools or data. The default | |
implementation simply returns a VelocityContext object with the request | |
and response objects placed inside. The request and response objects are | |
wrapped in simple wrapper classes to avoid introspection problems that may | |
occurr in some servlet container implementations. You can use the request | |
and repsponse objects normally, accessing methods of either from the | |
template. Just note that they aren't specifically javax.servlet.XXXX | |
classes, if that is important to you. | |
</blockquote> | |
<i><code>void setContentType( HttpServletRequest,HttpServletResponse )</code></i> | |
<blockquote> | |
Allows you to examine the request and set the content type yourself, | |
depending on the request or client. The default implementation sets | |
the content type to be that either specified in the | |
velocity.properties, if any, or the default, "text/html" if not | |
specified in the properties. | |
</blockquote> | |
<i><code>void mergeTemplate( Template, Context, HttpServletResponse )</code></i> | |
<blockquote> | |
Allows you to produce the output stream. The VelocityServlet uses a | |
pool of very efficient Writer classes, so this would usually be | |
overridden in special situations. | |
</blockquote> | |
<i><a name="requestCleanup()"><code>void requestCleanup( HttpServletRequest, | |
HttpServletResponse , Context )</code></a></i> | |
<blockquote> | |
Allows you to do any cleanup or resource reclamation at the end of the | |
request processing. The default does nothing. | |
</blockquote> | |
<i><a name="error()"><code>protected void error( HttpServletRequest, | |
HttpServletResponse, Exception )</code></a></i> | |
<blockquote> | |
Error handler that is called an exception occurrs in request | |
processing. Default implementation will send a simple HTML message | |
with stacktrace and exception information back to the user. Override | |
for custom client messages and more advanced problem handling. | |
</blockquote> | |
For further information, please see the Javadoc API documentation. | |
</p> | |
<a name="Deployment"><strong>Deployment</strong></a> | |
<p> | |
When you deploy your Velocity-based servlets, you will certainly want to | |
ensure that your properties file is used to configure the Velocity runtime. | |
Under Tomcat, one way to accomplish this is by placing your velocity.properties | |
file into the root directory of your web app (webapps/appname ) and then | |
add the following to your WEB-INF/web.xml file : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
<servlet> | |
<servlet-name>MyServlet</servlet-name> | |
<servlet-class>com.foo.bar.MyServlet</servlet-class> | |
<init-param> | |
<param-name>properties</param-name> | |
<param-value>/velocity.properties</param-value> | |
</init-param> | |
</servlet> | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
Assuming all is right, this will ensure that when MyServlet is loaded, | |
it will use the velocity.properties file to initialize itself | |
rather than relying on it's internal defaults. | |
</p> | |
<p> | |
Note that Velocity uses a singleton model for it's central core Runtime | |
class, so it is a very good idea to put the velocity-XX.jar | |
into the WEB-INF/lib directory in all web applications that use | |
Velocity to ensure that the web app classloader is | |
managing your Runtime instance, rather than putting it in the CLASSPATH | |
or the top level lib directory of the servlet runner. | |
</p> | |
<p> | |
This deployment method will ensure that different web applications will | |
not be subject to Velocity configuration conflicts. | |
</p> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="Using Velocity In General Applications"><strong>Using Velocity In General Applications</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<p> | |
As Velocity was designed to be a general-use tool, it is just as useful in | |
general application programs as it is servlets. In general, you can use the | |
same programming pattern discussed at the beginning of this guide, but there | |
are a few utility methods provided for application use, just like we provide | |
the VelocityServlet base class for ease of use in servlet programming. | |
The only new responsibility you have as the application programmer is to | |
initialize the Velocity runtime engine, but that is easy. | |
</p> | |
<a name="The Velocity Helper Class"><strong>The Velocity Helper Class</strong></a> | |
<p> | |
Velocity contains an application utility class called Velocity | |
( <code>org.apache.velocity.app.Velocity</code> ). The purpose of this class | |
is to provide the necessary methods required to initialize Velocity, as well as | |
useful utility routines to make life easier in using Velocity. This class is | |
documented in the project's javadoc, so please look there for definitive | |
details. This documentation is intended to be of a tutorial nature; therefore | |
for compete API information, the Javadoc is the definitive source. | |
</p> | |
<p> | |
The Velocity runtime engine is a singleton instance that provides resource, | |
logging and other services to all Velocity users running in the same JVM. | |
Therefore, the runtime engine is initialized only once. You can attempt to | |
initialize Velocity more than once, but only the first initialization will | |
apply. The rest of the attempts will be ignored. The Velocity utility | |
class currently provides five methods used in configuration of the runtime engine. | |
</p> | |
<p> | |
The five configuration methods are : | |
</p> | |
<ul> | |
<li><code>setProperty( String key, Object o )</code><br /> | |
Sets the property <code>key</code> with the value <code>o</code>. The value | |
is typically a String, but in special cases can also be a comma-separated | |
list of values (in a single String, ex."foo, bar, woogie") as well as other | |
things that will arise. | |
</li> | |
<li><code>Object getProperty( String key )</code><br /> | |
Returns the value of the property key. Note that you must be aware of the | |
type of the return value, as they can be things other than Strings. | |
</li> | |
<li><code>init()</code><br /> | |
Initializes the runtime with the default properties provided in the | |
distribution.(These are listed below in the section pertaining to | |
properties.) | |
</li> | |
<li><code>init( Properties p )</code><br /> Initialize the runtime with the | |
properties contained in the <code>java.util.Properties</code> object passed | |
as an argument. | |
</li> | |
<li><code>init( String filename )</code><br /> initilizes the runtime | |
using the properties found in the properties file filename | |
</li> | |
</ul> | |
<p> | |
Note that in each case, the default properties will be used as a base | |
configuration, and any additional properties specified by the application | |
will replace individual defaults. Any default properties not overwritten | |
will remain in effect. This has the benefit that only the properties | |
you are interested in changing need to be specified, rather | |
than a complete set. | |
</p> | |
<p> | |
Another thing to note is that the <code>init()</code> calls may be called | |
more than once without harm in an application. However, the first call to any | |
of the <code>init()</code> functions will configure the engine with the | |
configuration properties set at that point, and any further configuration | |
changes or <code>init()</code> calls will be ignored. | |
</p> | |
<p> | |
The most common approaches to initializing Velocity will be something like : | |
</p> | |
<ol> | |
<li> Setup the configuration values you wish to set in a file in the same | |
format as org/apache/velocity/runtime/defaults/velocity.properties | |
(the default set), or in a <code>java.util.Properties</code>, and then | |
call either <code>init( filename )</code> or <code>init( Properties )</code> | |
</li> | |
<li> Set the configuration values individually using <code>setProperty()</code> | |
and then call <code>init()</code>. This method is generally used by more advanced | |
applications that already have their own configuration management system - | |
this allows the application so configure Velocity based upon values it generates | |
at runtime, for example. | |
</li> | |
</ol> | |
<p> | |
Once the runtime is initialized, you can do with it what you wish.. This mostly | |
revolves around rendering templates into an output stream, and the Velocity | |
utility class allows you to do this easily. Currently, here are the methods | |
and a brief description of what they do : | |
</p> | |
<ul> | |
<li> | |
<code> evaluate( Context context, Writer out, String logTag, | |
String instring )</code><br /> | |
<code>evaluate( Context context, Writer writer, String logTag, | |
InputStream instream )</code><br /> | |
These methods will render the input, in either the form of String or | |
InputStream to an output Writer, using a Context that you provide. | |
This is a very convenienient method to use for token replacement of | |
strings, or if you keep 'templates' of VTL-containing content in a | |
place like a database or other non-file storage, or simply generate such | |
dynamically. | |
</li> | |
<li> | |
<code>invokeVelocimacro( String vmName, String namespace, String params[], | |
Context context, Writer writer )</code><br /> | |
Allows direct access to Velocimacros. This can also be accomplished | |
via the <code>evaluate()</code> method above if you wish. Here you | |
simply name the vm you wish to be called, create an array of args to the VM, | |
a Context of data, and Writer for the output. Note that the VM args | |
must be the 'keys' of the data objects in the Context, rather than | |
literal data to be used as the arg. This will probably change. | |
</li> | |
<li> | |
<code>mergeTemplate( String templateName, Context context, Writer writer ) | |
</code><br /> | |
Convenient access to the normal template handling and rendering services | |
of Velocity. This method will take care of getting and rendering the | |
template. It will take advantage of loading the template according | |
to the properties setting for the file resource loader, and therefore | |
provides the advantage of file and parsed template caching that Velocity | |
offers. This is the most efficient way to access templates, | |
and is recommended unless you have special needs. | |
</li> | |
<li> | |
<code> boolean templateExists( String name ) </code><br /> | |
Determines if a template <code>name</code> is able to be found by | |
the currently configured resource loaders. | |
</li> | |
</ul> | |
<p> | |
Once we know about these basic helpers, it is easy to write Java program | |
that uses Velocity. Here it is: | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
import java.io.StringWriter; | |
import org.apache.velocity.app.Velocity; | |
import org.apache.velocity.VelocityContext; | |
public class Example2 | |
{ | |
public static void main( String args[] ) | |
{ | |
/* first, we init the runtime engine. Defaults are fine. */ | |
Velocity.init(); | |
/* lets make a Context and put data into it */ | |
VelocityContext context = new VelocityContext(); | |
context.put("name", "Velocity"); | |
context.put("project", "Jakarta"); | |
/* lets render a template */ | |
StringWriter w = new StringWriter(); | |
Velocity.mergeTemplate("testtemplate.vm", context, w ); | |
System.out.println(" template : " + w ); | |
/* lets make our own string to render */ | |
String s = "We are using $project $name to render this."; | |
w = new StringWriter(); | |
Velocity.evaluate( context, w, "mystring", s ); | |
System.out.println(" string : " + w ); | |
} | |
} | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
When we run this program, and have the template <code> testtemplate.vm</code> | |
in the same directory as our program (because we used the default | |
configuration properties, and the defaul place to load templates | |
from is the current directory...), our output should be : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
template : Hi! This Velocity from the Jakarta project. | |
string : We are using Jakarta Velocity to render this. | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
where the template we used, testtemplate.vm, is | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
Hi! This $name from the $project project. | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
That's all there is to it! Note that we didn't have to use both | |
<code>mergeTemplate()</code> and <code>evaluate()</code> in our | |
program. They are both included there for demonstration purposes. | |
You will probably use only one of the methods, but depending | |
on you application requirements, you are free to do what you wish. | |
</p> | |
<p> | |
This appears to be a little different from the 'fundamental pattern' | |
that was mentioned at the beginning of this guide, but it really is the | |
same thing. First, you are making a context and filling it with | |
the data needed. Where this examples differs is that in the part of | |
the above example where <code>mergeTemplate()</code> is used, | |
<code>mergeTemplate()</code> is doing the work of getting the template | |
and merging it for you, using the lower-level calls in the Runtime class. | |
In the second example, you are making your template dynamically via the | |
String, so that is analgous to the 'choose template' part of the process, | |
and the <code>evaluate()</code> method does the merging for you using | |
lower level calls. | |
</p> | |
<p> | |
So the example above sticks to the same simply pattern of using the Velocity | |
template engine, but the utility functions do some of | |
the repeated drudge work, or allow you other options for your | |
template content other than template files. | |
</p> | |
<a name="Exceptions"><strong>Exceptions</strong></a> | |
<p> | |
There are three exceptions that Velocity will throw during the parse / merge cycle. | |
This are additional to the exceptions that will come from IO problems, etc. | |
They are found in the package <code>org.apache.velocity.exception</code> and are: | |
</p> | |
<ol> | |
<li> | |
<code>ResourceNotFoundException</code><br /> | |
Thrown when the resource managment system cannot find a resource (template) that | |
was requested. | |
</li> | |
<li> | |
<code>ParseErrorException</code><br /> | |
Thrown when a VTL syntax error is found when parsing a resource (template). | |
</li> | |
<li> | |
<code>MethodInvocationException</code><br /> | |
Thrown when a method of object in the context thrown an exception during | |
render time. This exception wraps the thrown exception and propogates it | |
to the application. This allows you to handle problems in your own objects | |
at runtime. | |
</li> | |
</ol> | |
<p> | |
In each case, a message is put into the runtime log. For more information, | |
see the Javadoc API documentation. | |
</p> | |
<a name="Miscellaneous Details"><strong>Miscellaneous Details</strong></a> | |
<p> | |
While the above example used the default properties, setting your own | |
properties is very simple. All you have to do is make a properties file | |
somewhere and pass the name of that file to the <code>init(String)</code> | |
method of the Velocity utility class, or make a | |
<code>java.util.Properties</code> object, add the desired properties and | |
values, and pass that to the <code>init(Properties)</code> method. | |
The latter method is convenient, because you can either fill it directly | |
from a separate properties file via the <code>load()</code> method, or even | |
better, you can fill it dynamically from your own application / framework's | |
property set at runtime. This gives you the freedom to combine all of the | |
properties for your app into one properties file. | |
</p> | |
<p> | |
If we wanted to use a different directory than the current directory to | |
load our template from, we could do something like this : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
... | |
import java.util.Properties; | |
... | |
public static void main( String args[] ) | |
{ | |
/* first, we init the runtime engine. */ | |
Properties p = new Properties(); | |
p.setProperty("file.resource.loader.path", "/opt/templates"); | |
Velocity.init( p ); | |
/* lets make a Context and put data into it */ | |
... | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
And, assuming you have a directory <code>/opt/templates</code> and the template | |
<code>testtemplate.vm</code> is in there, then things would work just fine. | |
If you try this and have a problem, be sure to look at the velocity.log for | |
information - the error messages are pretty good for figuring out what is wrong. | |
</p> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="Application Attributes"><strong>Application Attributes</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<p> | |
<i>Application Attributes</i> are name-value pairs that can be associated with | |
a RuntimeInstance (either via the <code>VelocityEngine</code> or | |
the <code>Velocity</code> singleton) and accessed from any part of the Velocity | |
engine that has access to the RuntimeInstance. | |
</p> | |
<p> | |
This feature was designed for applications that need to communicate between | |
the application layer and custom parts of the Velocity engine, such as | |
loggers, resource loaders, resource managers, etc. | |
</p> | |
<p> | |
The Application Attribute API is very simple. From the application layer, there | |
is a method of the <code>VelocityEngine</code> and the <code>Velocity</code> | |
classes : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
public void setApplicationAttribute( Object key, Object value ); | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
through which an application can store on Object under an application (or | |
internal component) specified key. There are no restrictions on the key | |
or the value. The value for a key may be set at any time - it is not required | |
that this be set before init() is called. | |
</p> | |
<p> | |
Internal components can access the key-value pairs if they have access to the | |
object via the <code>RuntimeServices</code> interface, using the method | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
public Object getApplicationAttribute( Object key ); | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
Note that internal components cannot set the value of the key, just get it. | |
if the internal component must communicate information to the application layer, | |
it must do so via the Object passed as the value. | |
</p> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="EventCartridge and Event Handlers"><strong>EventCartridge and Event Handlers</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<p> | |
Starting in version 1.1, a fine-grain event handling system was added to Velocity. | |
The EventCartridge is a class in which you register your event handlers, and then the | |
EventCartridge acts as the delivery agent from which the Velocity engine will | |
access the event handlers at merge time if needed. | |
Currently, there are 3 events that can be handled, and all are found in the | |
<code>org.apache.velocity.app.event</code> package. | |
</p> | |
<p> | |
<i><code>org.apache.velocity.app.event.NullSetEventHandler</code></i> | |
<blockquote> | |
When a #set() results in a null assignment, this is normally | |
logged. The <code>NullSetEventHandler</code> allows you to 'veto' the | |
logging of this condition. | |
<br /> | |
<pre> | |
public interface NullSetEventHandler extends EventHandler | |
{ | |
public boolean shouldLogOnNullSet( String lhs, String rhs ); | |
} | |
</pre> | |
</blockquote> | |
<i><code>org.apache.velocity.app.event.ReferenceInsertionEventHandler</code></i> | |
<blockquote> | |
A <code>ReferenceInsertionEventHandler</code> allows the | |
developer to intercept each write of a reference ($foo) value to the output | |
stream and modify that output. | |
<pre> | |
public interface ReferenceInsertionEventHandler extends EventHandler | |
{ | |
public Object referenceInsert( String reference, Object value ); | |
} | |
</pre> | |
</blockquote> | |
<i><code>org.apache.velocity.app.event.MethodExceptionEventHandler</code></i> | |
<blockquote> | |
When a user-supplied method throws an exception, the | |
<code>MethodExceptionEventHandler</code> is invoked with the Class, method name | |
and thrown Exception. The handler can either return a valid Object to be used | |
as the return value of the method call, or throw the passed-in or new Exception, | |
which will be wrapped and propogated to the user as a | |
<code>MethodInvocationException</code> | |
<pre> | |
public interface MethodExceptionEventHandler extends EventHandler | |
{ | |
public Object methodException( Class claz, String method, Exception e ) | |
throws Exception; | |
} | |
</pre> | |
</blockquote> | |
</p> | |
<p> | |
<strong>Using the EventCartridge</strong> | |
</p> | |
<p> | |
Using the EventCartridge is fairly straightforward. The following abbreviated | |
example was taken from <code>org.apache.velocity.test.misc.Test</code>. | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
... | |
import org.apache.velocity.app.event.EventCartridge; | |
import org.apache.velocity.app.event.ReferenceInsertionEventHandler; | |
import org.apache.velocity.app.event.MethodExceptionEventHandler; | |
import org.apache.velocity.app.event.NullSetEventHandler; | |
... | |
public class Test implements ReferenceInsertionEventHandler, | |
NullSetEventHandler, | |
MethodExceptionEventHandler | |
{ | |
public void myTest() | |
{ | |
.... | |
/* | |
* now, it's assumed that Test implements the correct methods to | |
* support the event handler interfaces. So to use them, first | |
* make a new cartridge | |
*/ | |
EventCartridge ec = new EventCartridge(); | |
/* | |
* then register this class as it contains the handlers | |
*/ | |
ec.addEventHandler(this); | |
/* | |
* and then finally let it attach itself to the context | |
*/ | |
ec.attachToContext( context ); | |
/* | |
* now merge your template with the context as you normally | |
* do | |
*/ | |
.... | |
} | |
/* | |
* and now the implementations of the event handlers | |
*/ | |
public Object referenceInsert( String reference, Object value ) | |
{ | |
/* do something with it */ | |
return value; | |
} | |
public boolean shouldLogOnNullSet( String lhs, String rhs ) | |
{ | |
if ( /* whatever rule */ ) | |
return false; | |
return true; | |
} | |
public Object methodException( Class claz, String method, Exception e ) | |
throws Exception | |
{ | |
if ( /* whatever rule */ ) | |
return "I should have thrown"; | |
throw e; | |
} | |
} | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="Velocity Configuration Keys and Values"><strong>Velocity Configuration Keys and Values</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<p> | |
Velocity's runtime configuration is controlled by a set of configuration keys | |
listed below. Generally, these keys will have values that consist of either a | |
String, or a comma-separated list of Strings, referred to as a CSV for | |
comma-separated values. | |
</p> | |
<p> | |
There is a set of default values contained in Velocity's jar, found in | |
/src/java/org/apache/velocity/runtime/defaults/velocity.defaults, that | |
Velocity uses as it's configuration baseline. | |
This ensures that Velocity will always have a 'correct' value | |
for it's configuration keys at startup, although it may not be what you want. | |
</p> | |
<p> | |
Any values specified before init() time will replace the default values. | |
Therefore, you only have toconfigure velocity with the values for the keys | |
that you need to change, and not worry about the rest. Further, as we add more | |
features and configuration capability, you don't have to change your | |
configuration files to suit - the Velocity engine will always have default | |
values. | |
</p> | |
<p> | |
Please sees the section above <a href="developer-guide.html#Using Velocity In General Applications"><b>Using Velocity In General | |
Applications</b></a> for discussion on the configuration API. | |
</p> | |
<p> | |
Below are listed the configuration keys that control Velocity's behavior. | |
Organized by category, each key is listed with it's current default value | |
to the right of the '=' sign. | |
</p> | |
<p> | |
<strong>Runtime Log</strong> | |
</p> | |
<p> | |
<code>runtime.log = velocity.log</code><br /> | |
Full path and name of log file for error, warning, | |
and informational messages. The location, if not absolute, is | |
relative to the 'current directory'. | |
</p> | |
<p> | |
<code>runtime.log.logsystem</code><br /> | |
This property has no default value. It is used to give Velocity an | |
instantiated instance of a logging class that supports the interface | |
<code>org.apache.velocity.runtime.log.LogSystem.</code>, which allows | |
the combination of Velocity log messages with your other application | |
log messages. Please see the section | |
<a href="developer-guide.html#Configuring the Log System">Configuring the Log System</a> | |
for more information. | |
</p> | |
<p> | |
<code>runtime.log.logsystem.class = | |
org.apache.velocity.runtime.log.AvalonLogSystem</code><br /> | |
Class to be used for the Velocity-instantiated log system. | |
</p> | |
<p> | |
<code>runtime.log.error.stacktrace = false</code><br /> | |
<code>runtime.log.warn.stacktrace = false</code><br /> | |
<code>runtime.log.info.stacktrace = false</code><br /> | |
Turns on stacktracing for the three error categories. | |
These produce a large amount of log output. | |
</p> | |
<p> | |
<code>runtime.log.invalid.references = true </code><br /> | |
Property to turn off the log output when a reference isn't valid. | |
Good thing to turn of in production, but very valuable | |
for debugging. | |
</p> | |
<p> | |
<code>runtime.log.logsystem.avalon.logger = <i>name</i> </code><br /> | |
Allows user to specify an existing logger <i>name</i> | |
in the Avalon hierarchy | |
without having to wrap with a LogSystem interface. <b>Note:</b> | |
You must also specify | |
<code>runtime.log.logsystem.class = | |
org.apache.velocity.runtime.log.AvalonLogSystem</code> as the default | |
logsystem may change. There is <b>no</b> guarantee that the Avalon | |
log system will remain the default log system. | |
</p> | |
<p> | |
<strong>Character Encoding</strong> | |
</p> | |
<p> | |
<code>input.encoding = ISO-8859-1</code><br /> | |
Character encoding for input (templates). Using this, you can use | |
alternative encoding for your templates, such as UTF-8. | |
</p> | |
<p> | |
<code>output.encoding = ISO-8859-1</code><br /> | |
Character encoding for output streams from the VelocityServlet and Anakia. | |
</p> | |
<p> | |
<strong>#foreach() Directive</strong> | |
</p> | |
<p> | |
<code>directive.foreach.counter.name = velocityCount</code><br /> | |
Used in the #foreach() directive, defines the string to be used as the | |
context key for the loop count. A template would access | |
the loop count as $velocityCount. | |
</p> | |
<p> | |
<code>directive.foreach.counter.initial.value = 1</code><br /> | |
Default starting value for the loop counter reference in a #foreach() loop. | |
</p> | |
<p> | |
<strong>#include() and #parse() Directive</strong> | |
</p> | |
<p> | |
<code>directive.include.output.errormsg.start | |
= <![CDATA[ <!-- include error : ]]> </code><br /> | |
<code>directive.include.output.errormsg.end | |
= <![CDATA[ see error log --> ]]></code><br /> | |
Defines the beginning and ending tags for an in-stream error message in the | |
case of a problem with the #include() directive. If both the .start and .end | |
tags are defined, an error message will be output to the stream, of the | |
form '.start msg .end' where .start and .end refer to the property values. | |
Output to the render stream will only occur if both the .start and .end | |
(next) tag are defined. | |
</p> | |
<p> | |
<code>directive.parse.maxdepth = 10</code><br /> | |
Defines the allowable parse depth for a template. A template may #parse() | |
another template which itself may have a #parse() directive. This value | |
prevents runaway #parse() recursion. | |
</p> | |
<p> | |
<strong>Resource Management</strong> | |
</p> | |
<p> | |
<code>resource.manager.logwhenfound = true</code><br /> | |
Switch to control logging of 'found' messages from resource manager. | |
When a resource is found for the first time, the resource name | |
and classname of the loader that found it will be noted in the | |
runtime log. | |
</p> | |
<p> | |
<code>resource.loader = <name> (default = File)</code><br /> | |
<i>Multi-valued key. Will accept CSV for value.</i> Pulic name of a | |
resource loader to be used. This public name will then be used | |
in the specification of the specific properties for that resource loader. | |
Note that as a multi-valued key, it's possible to pass | |
a value like "file, class" (sans quotes), indicating that following | |
will be configuration values for two loaders. | |
</p> | |
<p> | |
<code><name>.loader.description | |
= Velocity File Resource Loader</code><br /> | |
Description string for the given loader. | |
</p> | |
<p> | |
<code><name>.resource.loader.class | |
= org.apache.velocity.runtime.resource.loader.FileResourceLoader</code><br /> | |
Name of implementation class for the loader. The default loader | |
is the file loader. | |
</p> | |
<p> | |
<code><name>.resource.loader.path = .</code><br /> | |
<i>Multi-valued key. Will accept CSV for value.</i> Root(s) from which the | |
loader loads templates. Templates may live in subdirectories of this root. | |
ex. homesite/index.vm This configuration key applies currently to the | |
FileResourceLoader and JarResourceLoader. | |
</p> | |
<p> | |
<code><name>.resource.loader.cache = false</code><br /> | |
Controls caching of the templates in the loader. Default is false, to make | |
life easy for development and debugging. This should be set to true for | |
production deployment. When 'true', the <code>modificationCheckInterval</code> | |
property applies. This allows for the efficiency of caching, with the | |
convenience of controlled reloads - useful in a hosted or ISP environment | |
where templates can be modifed frequently and bouncing the application or | |
servlet engine is not desired or permitted. | |
</p> | |
<p> | |
<code><name>.resource.loader.modificationCheckInterval = 2</code><br /> | |
This is the number of seconds between modification checks when caching is | |
turned on. When this is an integer > 0, this represents the number of | |
seconds between checks to see if the template was modified. If the | |
template has been modified since last check, then it is reloaded and | |
reparsed. Otherwise nothing is done. When <= 0, no modification | |
checks will take place, and assuming that the property <code>cache</code> | |
(above) is true, once a template is loaded and parsed the first time it is used, | |
it will not be checked or reloaded after that until the application or | |
servlet engine is restarted. | |
</p> | |
<p> To illustrate, here is an example taken right from the default Velocity | |
properties, showing how setting up the FileResourceLoader is managed | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
resource.loader = file | |
file.resource.loader.description = Velocity File Resource Loader | |
file.resource.loader.class = | |
org.apache.velocity.runtime.resource.loader.FileResourceLoader | |
file.resource.loader.path = . | |
file.resource.loader.cache = false | |
file.resource.loader.modificationCheckInterval = 2 | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
<strong>Velocimacro</strong> | |
</p> | |
<p> | |
<code>velocimacro.library = VM_global_library.vm </code><br /> | |
<i>Multi-valued key. Will accept CSV for value.</i> | |
Filename(s) of Velocimacro library to be loaded when the Velocity | |
Runtime engine starts. These Velocimacros are accessable to all | |
templates. The file is assumed to be relative to the root of the | |
file loader resource path. | |
</p> | |
<p> | |
<code>velocimacro.permissions.allow.inline = true</code><br /> | |
Determines of the definition of new Velocimacros via the #macro() directive | |
in templates is allowed. The default value is true, meaning any template | |
can define and use new Velocimacros. Note that depending on other properties, | |
those #macro() statements can replace global definitions. | |
</p> | |
<p> | |
<code>velocimacro.permissions.allow.inline.to.replace.global = false </code><br /> | |
Controls if a Velocimacro defind 'inline' in a template can replace | |
a Velocimacro defined in a library loaded at startup. | |
</p> | |
<p> | |
<code>velocimacro.permissions.allow.inline.local.scope = false</code><br /> | |
Controls 'private' templates namespaces for Velocimacros. When true, a #macro() | |
directive in a template creates a Velocimacro that is accessable only from the | |
defining template. This means that Velocimacros cannot be shared unless they | |
are in the global or local library loaded at startup. (See above.) It also means | |
that templates cannot interfere with each other. This property also allows a technique | |
where there is a 'default' Velocimacro definition in the global or local library, | |
and a template can 'override' the implementation for use within that template. | |
This occurrs because when this property is true, the template's namespace is | |
searched for a Velocimacro before the global namespace, therefore allowing | |
the override mechanism. | |
</p> | |
<p> | |
<code>velocimacro.context.localscope = false</code><br /> | |
Controls whether reference access (set/get) within a Velocimacro will change | |
the context, or be of local scope in that | |
Velocimacro. | |
</p> | |
<p> | |
<code>velocimacro.library.autoreload = false</code><br /> | |
Controls Velocimacro library autoloading. When set to <code>true</code> | |
the source Velocimacro library for an invoked Velocimacro will be checked | |
for changes, and reloaded if necessary. This allows you to change and | |
test Velocimacro libraries without having to restart your application or | |
servlet container, just like you can with regular templates. | |
This mode only works when caching is <i>off</i> | |
in the resource loaders (e.g. <code>file.resource.loader.cache = false</code> ). | |
This feature is intended for development, not for production. | |
</p> | |
<p> | |
<strong>String Interpolation</strong> | |
</p> | |
<p> | |
<code>runtime.interpolate.string.literals = true</code><br /> | |
Controls interpolation mechanism of VTL String Literals. Note that a VTL | |
StringLiteral is specifically a string using double quotes that is used | |
in a #set() statement, a method call of a reference, a parameter to a VM, | |
or as an argument to a VTL directive in general. See the VTL reference for | |
further information. | |
</p> | |
<p> | |
<strong>Runtime Configuration</strong> | |
</p> | |
<p> | |
<code>parser.pool.size = 20</code><br /> | |
This property sets the number of parsers that Velocity will | |
create at startup and keep in a pool. The default of 20 parsers | |
should be more than enough for most uses. In the event | |
that Velocity does run out of parsers, it will indicate | |
so in the log, and | |
dynamically create them as needed. Note that they will not | |
be added to the pool. This is a slow operation compared to | |
the normal parser pooling, but this is considered an | |
exceptional condition. If you see a log message, please | |
increment this property. | |
</p> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="Configuring the Log System"><strong>Configuring the Log System</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<p> | |
Velocity has a few nice logging features to allow both simplicity and | |
flexibility. Without any extra configuration, Velocity will setup a | |
file-based logger that will output all logging messages to a file | |
called <code>velocity.log</code> in the 'current directory' where | |
Velocity was initialized. For more advanced users, you may integrate | |
your current logging facilities with Velocity to have all log messages | |
sent to your logger. | |
</p> | |
<p> | |
Starting with version 1.3, Velocity will automatically use either the | |
<a href="http://jakarta.apache.org/avalon/logkit/index.html"> | |
Jakarta Avalon Logkit</a> logger, or the | |
<a href="http://jakarta.apache.org/log4j/">Jakarta Log4j</a> logger. | |
It will do so by using whatever it finds in the current classpath, starting | |
first with Logkit. If Logkit isn't found, it tries Log4j. | |
</p> | |
<p> | |
To utilize this feature, simply use the 'non-dependency' Velocity jar | |
(because Logkit is baked into the jar with dependencies) and place | |
either the logkit or log4j jar in your classpath. | |
</p> | |
<p> | |
In general, you have the following logging options : | |
</p> | |
<ul> | |
<li> | |
<b>Default Configuration</b><br /> | |
By default, Velocity will create a file-based logger in the current | |
directory. See the note above regarding automatic detection of | |
Logkit or Log4j to use as the default logging system. | |
</li> | |
<li> | |
<b>Existing Log4j Category</b><br /> | |
Starting with version 1.3, Velocity will log it's output to an existing | |
Log4j Category setup elsewhere in the application. To use this feature | |
you must | |
<ol> | |
<li> | |
Make sure that the Log4j jar is in your classpath. (You would do this | |
anyway since you are using Log4j in the application using Velocity.) | |
</li> | |
<li> | |
Configure Velocity to use the <code>SimpleLog4jLogSystem</code> class. | |
</li> | |
<li> | |
Specify the name of the existing Category to use via the | |
'runtime.log.logsystem.log4j.category' property. | |
</li> | |
</ol> | |
This approach replaces and deprecates the older <code>Log4JLogSystem</code> | |
class. To see how this is done in code, see the example below. | |
</li> | |
<li> | |
<b>Custom Standalone Logger</b><br /> | |
You can create a custom logging class - you simply must implement the | |
interface <code>org.apache.velocity.runtime.log.LogSystem</code> and | |
then simply set the configuration property | |
<code>runtime.log.logsystem.class</code> with the | |
classname, and Velocity will create an instance of that class at init time. | |
You may specify the classname as you specify any other properties. See | |
the information on the | |
<a href="developer-guide.html#Using Velocity In General Applications"> | |
Velocity helper class</a> as well as the | |
<a href="developer-guide.html#Velocity Configuration Keys and Values"> | |
configuration keys and values.</a> | |
Please note that through oversight, the interface to | |
<code>org.apache.velocity.runtime.log.LogSystem</code> | |
was changed in v1.2 to support the separable instances of the Velocity | |
runtime. If you have an exisiting pre v1.2 custom logger that is going | |
to be instantiated by the Velocity LogManager, you must add the | |
<code>init( RuntimeServices )</code> method. | |
</li> | |
<li> | |
<b>Integrated Logging</b><br /> | |
You can integrate Velocity's logging capabilities with your applications | |
existing logging system, simply by implementing the | |
<code>org.apache.velocity.runtime.log.LogSystem</code> interface. Then, | |
pass an instance of your logging class to Velocity via the | |
<code>runtime.log.logsystem</code> configuration key before | |
initializing the Velocity engine, | |
and Velocity will log messages to your applications logger. | |
See the information on the | |
<a href="developer-guide.html#Using Velocity In General Applications">Velocity helper class</a> | |
as well as the | |
<a href="developer-guide.html#Velocity Configuration Keys and Values">configuration keys and values.</a> | |
</li> | |
</ul> | |
<a name="Using Log4j With Existing Category"><strong>Using Log4j With Existing Category</strong></a> | |
<p> | |
Here is an example of how to configure Velocity to log to an existing Log4j | |
Category. | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
import org.apache.velocity.app.VelocityEngine; | |
import org.apache.velocity.runtime.RuntimeConstants; | |
import org.apache.log4j.Category; | |
import org.apache.log4j.BasicConfigurator; | |
public class Log4jCategoryExample | |
{ | |
public static String CATEGORY_NAME = "velexample"; | |
public static void main( String args[] ) | |
throws Exception | |
{ | |
/* | |
* configure log4j to log to console | |
*/ | |
BasicConfigurator.configure(); | |
Category log = Category.getInstance( CATEGORY_NAME ); | |
log.info("Hello from Log4jCategoryExample - ready to start velocity"); | |
/* | |
* now create a new VelocityEngine instance, and | |
* configure it to use the category | |
*/ | |
VelocityEngine ve = new VelocityEngine(); | |
ve.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, | |
"org.apache.velocity.runtime.log.SimpleLog4JLogSystem" ); | |
ve.setProperty("runtime.log.logsystem.log4j.category", CATEGORY_NAME); | |
ve.init(); | |
log.info("this should follow the initialization output from velocity"); | |
} | |
} | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
Note that the above example can be found in <code>examples/logger_example</code>. | |
</p> | |
<a name="Simple Example of a Custom Logger"><strong>Simple Example of a Custom Logger</strong></a> | |
<p> | |
Here is an example of how to use an instantiation of your class that implements | |
Velocity's logging system as the logger. Note that we are not passing the name | |
of the class to use, but rather a living, existing instantiation of the class | |
to be used. All that is required is that it support the | |
<code>LogSystem</code> interface. | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
import org.apache.velocity.runtime.log.LogSystem; | |
import org.apache.velocity.runtime.RuntimeServices; | |
... | |
public class MyClass implements LogSystem | |
{ | |
... | |
public MyClass() | |
{ | |
... | |
try | |
{ | |
/* | |
* register this class as a logger | |
*/ | |
Velocity.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, this ); | |
Velocity.init(); | |
} | |
catch (Exception e) | |
{ | |
/* | |
* do something | |
*/ | |
} | |
} | |
/** | |
* This init() will be invoked once by the LogManager | |
* to give you current RuntimeServices intance | |
*/ | |
public void init( RuntimeServices rsvc ) | |
{ | |
// do nothing | |
} | |
/** | |
* This is the method that you implement for Velocity to call | |
* with log messages. | |
*/ | |
public void logVelocityMessage(int level, String message) | |
{ | |
/* do something useful */ | |
} | |
... | |
} | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="Configuring Resource Loaders"><strong>Configuring Resource Loaders</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<a name="Resource Loaders"><strong>Resource Loaders</strong></a> | |
<p> | |
One of the fundamental and important parts about Velocity is the resource | |
management system and the resource loaders. They are referred to as 'resources' | |
here rather than 'templates' because the resource management system will also | |
handle non-template reasources, specifically things that are loaded via the | |
#include() directive. | |
</p> | |
<p> | |
The resource loader system if very flexible, allowing one or more resource | |
loaders to be in operation at the same time. This allows tremendous | |
flexibility in configuration and resource managment, and futher allows you | |
to write your own resource loaders for your special needs. | |
</p> | |
<p> | |
There are currently four kinds of resource loaders that are included with Velocity, | |
each described below. Note that in the example configuration properties given, | |
a common name for the loader is shown | |
(ex.'file' in <code>file.resource.loader.path</code>). This 'common name' | |
may not work for your configuration. Please read the section on | |
<a href="developer-guide.html#Velocity Configuration Keys and Values">resource configuration properties</a> | |
to understand how this system works. Also, each of these loaders is | |
located in the package <code>org.apache.velocity.runtime.resource.loader</code>. | |
</p> | |
<ul> | |
<li> | |
<b>FileResourceLoader :</b> This loader gets resources from the filesystem. It's | |
configuration properties include : | |
<ul> | |
<li> | |
<code>file.resource.loader.path</code> = <path to root of templates> | |
</li> | |
<li> | |
<code>file.resource.loader.cache</code> = true/false | |
</li> | |
<li> | |
<code>file.resource.loader.modificationCheckInterval</code> = <seconds between checks> | |
</li> | |
</ul> | |
This is the default loader, and is configured, by default to get templates from the | |
'current directory'. In the case of using Velocity with servlets, this can be a problem | |
as you don't want to have to keep your templates in the directory from which you start | |
your servlet engine. Please see the section on | |
<a href="developer-guide.html#Using Velocity In Servlets"> developing servlets with Velocity</a> | |
for more information. | |
</li> | |
<li> | |
<b>JarResourceLoader :</b> This loader gets resource from specific jar files. It is very | |
similar to the FileResourceLoader, except that you have the convenience of bundling | |
your templates into jars. The properties are identical, except for | |
<code>jar.resource.loader.path</code>, where you provide the full location of | |
the jar(s) you wish to load resources from. To specify a jar for the loader.path | |
you use the standard JAR URL syntax of <code>java.net.JarURLConnection</code>. | |
</li> | |
<li> | |
<b>ClasspathResourceLoader :</b> This loader gets resources from the classloader. | |
In general, this means that the ClasspathResourceLoader will load | |
templates placed in the classpath (in jars, for example) | |
While the | |
classpath is a source of great pain and suffering in general, it is a very useful | |
mechanism when working on a Servlet Spec 2.2 (or newer) compliant servlet runner. | |
<a href="http://jakarta.apache.org/tomcat/">Tomcat</a> | |
is an example of such. To use this loader effectively, all you must do is | |
jar your templates, and put that jar into the WEB-INF/lib directory of your | |
webapp. There are no configuration options to worry about, nor is the absolute vs. | |
relative path an issue, as it is with Jar and File resource loaders. | |
Again, please note that the ClasspathResourceLoader is not only for use with a | |
servlet container, but can be used in any application context. | |
</li> | |
<li> | |
<b>DataSourceResourceLoader :</b> This loader will load resources from a DataSource | |
such as a database. This loader is not built as part of the standard build | |
as it requires J2EE support. To build this loader, please download the J2EE | |
distribution, move the j2ee.jar into the <code>build/lib</code> directory, | |
and then build the new velocity jar with the <code>jar-j2ee</code> build target. | |
For more information on this loader, please see the javadoc for the class | |
<code>org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader</code>. | |
</li> | |
</ul> | |
<a name="Configuration Examples"><strong>Configuration Examples</strong></a> | |
<p> | |
Configuring the resource loaders for Velocity is straightforward. | |
The properties that control the are listed in the | |
<a href="developer-guide.html#Configuring Resource Loaders">resource configuration</a> | |
section, for further reference. | |
</p> | |
<p> | |
The first step in configuring one or more resource loaders is do | |
'declare' them by name to Velocity. Use the property | |
<code>resource.loader</code> and list one or more loader names. | |
You can use anything you want - these names are used to associate | |
configuration properties with a given loader. | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
resource.loader = file | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
That entry declares that we will have a resource loader known as 'file'. | |
The next thing to do is to set the important properties. The most critical | |
is to declare the class to use as the loader : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
file.resource.loader.class = | |
org.apache.velocity.runtime.resource.loader.FileResourceLoader | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
In this case, we are telling velocity that we are setting up | |
a resource loadercalled 'file', and are using the class | |
<code> | |
org.apache.velocity.runtime.resource.loader.FileResourceLoader | |
</code> | |
to be the class to use. | |
The next thing we do is set the properties important | |
to this loader. | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
file.resource.loader.path = /opt/templates | |
file.resource.loader.cache = true | |
file.resource.loader.modificationCheckInterval = 2 | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
Here, we set a few things. First, we set the path to find | |
the templates to be <code>/opt/templates</code>. Second, we | |
turned caching on, so that after a template or static file | |
is read in, it is cached in memory. And finally, we set | |
the modification check interval to 2 seconds, allowing Velocity | |
to check for new templates. | |
</p> | |
<p> | |
Those are the basics. What follows are a few examples of different configuraitons. | |
</p> | |
<p> | |
<b>Do-nothing Default Configuration : </b> As the name says, there is nothing | |
you have to do or configure to get the default configuration. This configuration | |
uses the FileResourceLoader with the current directory as the default resource | |
path, and caching is off. As a properties set, this is expressed as : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
resource.loader = file | |
file.resource.loader.description = Velocity File Resource Loader | |
file.resource.loader.class = | |
org.apache.velocity.runtime.resource.loader.FileResourceLoader | |
file.resource.loader.path = . | |
file.resource.loader.cache = false | |
file.resource.loader.modificationCheckInterval = 0 | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
<b>Multiple Template Path Configuration : </b> This configuration | |
uses the FileResourceLoader with several directories as 'nodes' on the | |
template search path. We also want to use caching, and have the templates | |
checked for changes in 10 second intervals. As a properties set, this is expressed as : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
resource.loader = file | |
file.resource.loader.description = Velocity File Resource Loader | |
file.resource.loader.class = | |
org.apache.velocity.runtime.resource.loader.FileResourceLoader | |
file.resource.loader.path = /opt/directory1, /opt/directory2 | |
file.resource.loader.cache = true | |
file.resource.loader.modificationCheckInterval = 10 | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
<b>Multiple Loader Configuration :</b> This configuration sets up | |
three loaders at the same time, the FileResourceLoader, | |
the ClasspathResourceLoader, and the JarResourceLoader. | |
The loaders are set-up such that the | |
FileResourceLoader is consulted first, then the | |
ClasspathResourceLoader, and finally the JarResourceLoader. | |
This would allow you to qickly | |
drop a template into the file template area to replace on of the | |
templates found in the classpath (usually via a jar) without | |
having to rebuild the jar. | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
# | |
# specify three resource loaders to use | |
# | |
resource.loader = file, class, jar | |
# | |
# for the loader we call 'file', set the FileResourceLoader as the | |
# class to use, turn off caching, and use 3 directories for templates | |
# | |
file.resource.loader.description = Velocity File Resource Loader | |
file.resource.loader.class = | |
org.apache.velocity.runtime.resource.loader.FileResourceLoader | |
file.resource.loader.path = templatedirectory1, anotherdirectory, foo/bar | |
file.resource.loader.cache = false | |
file.resource.loader.modificationCheckInterval = 0 | |
# | |
# for the loader we call 'class', use the ClasspathResourceLoader | |
# | |
class.resource.loader.description = Velocity Classpath Resource Loader | |
class.resource.loader.class = | |
org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader | |
# | |
# and finally, for the loader we call 'jar', use the JarResourceLoader | |
# and specify two jars to load from | |
# | |
jar.resource.loader.description = Velocity Jar Resource Loader | |
jar.resource.loader.class = | |
org.apache.velocity.runtime.resource.loader.JarResourceLoader | |
jar.resource.loader.path = | |
jar:file:/myjarplace/myjar.jar, jar:file:/myjarplace/myjar2.jar | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
Node that the three names 'file', 'class', and 'jar' are merely for your convenience and | |
sanity. They can be anything you want - they are just used to associate a set of | |
properties together. However, it is recommended that you use names that give some hint | |
of the function. | |
</p> | |
<p> | |
Note that while all three require very little configuration information | |
for proper operation, the ClasspathResourceLoader is the simplest. | |
</p> | |
<a name="Resource Manager and Cache" /> | |
<strong>Pluggable Resource Manager and Resource Cache</strong> | |
<p> | |
The Resource Manager is the main part of the resource (template and static content) | |
management system, and is responsible for taking application requests for | |
templates, finding them in the available resource loaders, and then optionally | |
caching the parsed template. The Resource Cache is the mechanism that the | |
Resource Manager uses to cache templates for quick reuse. While the default | |
versions of these two facilities are suitable for most | |
applications, for advanced users it now is possible | |
to replace the default resource manager | |
and resource cache with custom implementations. | |
</p> | |
<p> | |
A resource manager implementation must implement the | |
<code>org.apache.velocity.runtime.resource.ResourceManager</code> interface. | |
A description of the requirements of a resource manager is out of scope for | |
this document. Implementors are encouraged to review the default implementation. | |
To configure Velocity to load the replacement implementation, use the | |
configuration key : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
resource.manager.class | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
This key is also defined as a contstant | |
<code>RuntimeConstants.RESOURCE_MANAGER_CLASS</code> | |
</p> | |
<p> | |
A resource cache implementation must implement the | |
<code>org.apache.velocity.runtime.resource.ResourceCache</code> interface | |
As with the resource manager, a description of the requirements of a | |
resource manager is out of scope for | |
this document. Implementors are encouraged to review the default implementation. | |
To configure Velocity to load the replacement implementation, use the | |
configuration key : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
resource.manager.cache.class | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
This key is also defined as a contstant | |
<code>RuntimeConstants.RESOURCE_MANAGER_CACHE_CLASS</code> | |
</p> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="Template Encoding for Internationalization"><strong>Template Encoding for Internationalization</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<p> | |
As of version 1.1, Velocity allows you to specify the character encoding of your | |
template resources on a template by template basis. The normal resource | |
API's have been extended to take the encoding as an argument : | |
</p> | |
<p> | |
<code>org.apache.velocity.servlet.VelocityServlet</code> : <br /> | |
<blockquote> | |
<i><code> public Template getTemplate( String template, String encoding )</code></i> | |
</blockquote> | |
</p> | |
<p> | |
<code>org.apache.velocity.app.Velocity</code> : <br /> | |
<blockquote> | |
<i><code>public static Template getTemplate(String name, String encoding)</code></i> | |
<br /> | |
<br /> | |
<i><code>public static boolean mergeTemplate( String templateName, String encoding, Context context, Writer writer )</code></i> | |
<br /> | |
<i><code> </code></i> | |
</blockquote> | |
</p> | |
<p> | |
The value for the <i>encoding</i> argument is the conventional encoding specification | |
supported by your JVM, for example "UTF-8" or "ISO-8859-1". For the official names | |
for character sets, see <a href="http://www.iana.org/assignments/character-sets">here</a>. | |
</p> | |
<p> | |
Note that this applies only to the encoding of the template itself - the output | |
encoding is an application specific issue. | |
</p> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="Velocity and XML"><strong>Velocity and XML</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<p> | |
Velocity's flexibility and simple template language makes it an ideal environment | |
for working with XML data. <a href="anakia.html">Anakia</a> is an example of how | |
Velocity is used to replace XSL for rendering output from XML. The Velocity site, | |
including this documentation, is generated from XML source using Anakia. | |
The Jakarta site is also rendered using Anakia. | |
</p> | |
<p> | |
Generally, the pattern for dealing with XML in Velocity is to use something like | |
<a href="http://www.jdom.org/">JDOM</a> to process your XML into a data structure with | |
convenient Java access. Then, you produce templates that access data directly | |
out of the XML document - directly though the JDOM tree. For example, start | |
with an XML document such as : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
<?xml version="1.0"?> | |
<document> | |
<properties> | |
<title>Developer's Guide</title> | |
<author email="geirm@apache.org">Velocity Documentation Team</author> | |
</properties> | |
</document> | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
Now make a little Java program that includes code similar to: | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
... | |
SAXBuilder builder; | |
Document root = null; | |
try | |
{ | |
builder = new SAXBuilder( "org.apache.xerces.parsers.SAXParser" ); | |
root = builder.build("test.xml"); | |
} | |
catch( Exception ee) | |
{} | |
VelocityContext vc = new VelocityContext(); | |
vc.put("root", root ); | |
... | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
(See the Anakia source for details on how to do this, or the Anakia | |
example in the <code>examples</code> directory in the distribution.) | |
Now, make a regular Velocity template : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
<html> | |
<body> | |
The document title is | |
$root.getChild("document").getChild("properties").getChild("title").getText() | |
</body> | |
</html> | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
and render that template as you normally would, using the Context | |
containing the JDOM tree. Of course, this isn't the prettiest of | |
examples, but it shows the basics - that you can easily access XML data | |
directly from a Velocity template. | |
</p> | |
<p> | |
One real advantage of styling XML data in Velocity is that you have | |
access to any other object or data that the application provides. You | |
aren't limited to just using the data present in the XML document. | |
You may add anything you want to the context to provide additional | |
information for your output, or provide tools to help make working | |
with the XML data easier. Bob McWhirter's | |
<a href="http://sourceforge.net/projects/werken-xpath/"> Werken Xpath</a> | |
is one such useful tool - an example of how it is used in Anakia can be | |
found in <code>org.apache.velocity.anakia.XPathTool</code>. | |
</p> | |
<p> | |
One issue that arises with XML and Velocity is how to deal with XML | |
entities. One technique is to combine the use of Velocimacros | |
when you need to render an entity into the output stream : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
## first, define the Velocimacro somewhere | |
#macro( xenc $sometext )$tools.escapeEntities($sometext)#end | |
## and use it as | |
#set( $sometext = " < " ) | |
<text>#xenc($sometext)</text> | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
where the escapeEntities() is a method that does the escaping | |
for you. Another trick would be to create an encoding utility that takes the | |
context as a constructor parameter and only implements a method: | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
public String get(String key) | |
{ | |
Object obj = context.get(key) | |
return (obj != null) ? Escape.getText( obj.toString() ) : ""; | |
} | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
Put it into the context as "xenc". Then you can use it as : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
<text>$xenc.sometext</text> | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
This takes advantage of Velocity's introspection process - it will try | |
to call get("sometext") on the $xenc object in the Context - then the | |
xenc object can then get the value from the Context, encode it, and | |
return it. | |
</p> | |
<p> | |
Alternatively, since Velocity makes it easy to implement custom Context | |
objects, you could implement your own context which always applies the | |
encoding to any string returned. Be careful to avoid rendering the | |
output of method calls directly, as they could return objects or strings | |
(which might need encoding). Place them first into the context with a | |
#set() directive and the use that, for example : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
#set( $sometext = $jdomElement.getText() ) | |
<text>$sometext</text> | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
The previous suggestions for dealing with XML entities came from | |
Christoph Reck, an active participant in the Velocity community. We are | |
very grateful for his [unknowing] contribution to this document, and | |
hope his ideas weren't mangled too badly :) | |
</p> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="FAQ (Frequently Asked Questions)"><strong>FAQ (Frequently Asked Questions)</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<p> | |
In no apparent order, here are questions and answers that repeatedly arise | |
by developers using Velocity. As we get more, we will move this out to | |
a separate document. | |
</p> | |
<strong>Why Can't I Access Class Members and Constants from VTL?</strong> | |
<p> | |
The short answer is because we don't introspect for fields. We don't do that | |
because we wish to promote the idea that you hide your raw data in your | |
data objects. There are two solutions to this issue. The first is | |
that you should be writing accessors for data elements you wish to be | |
publicly exposed. That of course won't work for instances where you don't | |
have the source, or simply are too lazy. There is a class for the latter | |
group, <code>org.apache.velocity.app.FieldMethodizer</code> which introspects | |
your class, and exposes the public static fields in a way that allows easy | |
access from a template. Suppose you have a class : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
public class Foo | |
{ | |
public static String PATH_ROOT = "/foo/bar"; | |
.... | |
} | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
Then, in your code, you would put a <code>Foo</code> into the context like this | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
context.put("myfoo", new FieldMethodizer( new Foo() ) ); | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
Then to access this field in your template, you would simply access in | |
a manner similar to Java : | |
</p> | |
<div align="left"> | |
<table cellspacing="4" cellpadding="0" border="0"> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#ffffff"><pre> | |
$myfoo.PATH_ROOT | |
</pre></td> | |
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
<tr> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |
</tr> | |
</table> | |
</div> | |
<p> | |
If you have a crushing need to access public non-static members (or even private | |
if you are so driven), then you would have to exend / modify the | |
<code>FieldMethodizer</code> yourself. (And we still recommend you provide accessors....) | |
</p> | |
<strong>Where does Velocity look for Templates?</strong> | |
<p> | |
By default, without any configuration on your part, Velocity will look | |
for templates in files, and look for them in the current directory | |
(or relative to the current directory, if you prepend a path to your | |
template, like 'foo/bar.vm'). | |
</p> | |
<p> | |
Velocity does this to make it as easy as possible to use out of the box. | |
It has been argued that Velocity should do it from the 'root' directory, but | |
it's never clear what that is on filesystems where there are multiple roots | |
(like - "C:\", "D:\", etc). | |
</p> | |
<p> | |
For more information, see the section on | |
<a href="developer-guide.html#Configuring Resource Loaders"> | |
resource loaders</a> as well as the section on | |
<a href="developer-guide.html#Velocity Configuration Keys and Values"> | |
configuration keys, values and defaults</a>. | |
</p> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="Summary"><strong>Summary</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<p> | |
We hope this brief guide was a helpful introduction to using Velocity in | |
your Java projects, and thank you for you interest in Velocity. We | |
welcome any and all comments you may have about this documentation and | |
the Velocity template engine itself. | |
</p> | |
<p> | |
Please submit all detailed, thoughtful and constructive feedback through our | |
<a href="http://jakarta.apache.org/getinvolved/mail.html">mail lists</a>. | |
</p> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |
<tr><td bgcolor="#525D76"> | |
<font color="#ffffff" face="arial,helvetica,sanserif"> | |
<a name="Appendix 1 : Deploying the Example Servlet"><strong>Appendix 1 : Deploying the Example Servlet</strong></a> | |
</font> | |
</td></tr> | |
<tr><td> | |
<blockquote> | |
<p> | |
A continuing source of frustration for beginning servlet users is getting | |
all the pieces into place and working. Using a servlet engine like Tomcat or Resin | |
is far from obvious for the first time user (and even for more experienced users...). | |
The following are the basic instructions, to the best of our knowledge, for getting | |
the SampleServlet example working. Note that the sample template <code>sample.vm</code> | |
and the servlet code itself, <code>SampleServlet.java</code> are | |
found in the <code>examples/servlet_example</code> directory. Although some servlet | |
engines (Resin, for example) will compile the servlet for you, it would be best if | |
you compiled the examples first. To do this, see the section on building Velocity, and | |
use the <code>examples</code> target. | |
</p> | |
<p> | |
<a name="TomcatExample"><strong>Jakarta Tomcat</strong></a> | |
</p> | |
<p> | |
Setting up under <a href="http://jakarta.apache.org/tomcat/">Jakarta Tomcat</a> is fairly | |
straightforward. The 'webapp' directory is where Tomcat automatically | |
looks for it's 'web applications', so | |
this is where we will set things up. | |
</p> | |
<ol> | |
<li> First, make a new 'webapp' by creating a directory called <i>velexample</i> | |
in Tomcat's webapps directory, and make | |
a new directory structure as follows : | |
<blockquote> | |
velexample<br /> | |
velexample/WEB-INF<br /> | |
velexample/WEB-INF/lib<br /> | |
velexample/WEB-INF/classes<br /> | |
</blockquote> | |
</li> | |
<li> | |
Put the Velocity jar into the velexample/WEB-INF/lib directory. Note that with v1.2 | |
and newer, you either have to either use the jar from the distribution (or that you | |
build yourself) that contains all the dependencies ( ex. velocity-dep-1.2.jar) or | |
you must add the dependency jars yourself to the WEB-INF/lib directory. Please see | |
the section "Getting Started" and "Dependencies", above. | |
</li> | |
<li> | |
Put the SampleServlet.class into the velexample/WEB-INF/classes directory | |
</li> | |
<li> | |
Put the sample.vm template into the velexample directory. The SampleServlet is | |
written to use the root of the webapp as the source of the templates, so | |
no configuration is needed. | |
</li> | |
<li> | |
At this point, you should be able to start (or restart) Tomcat and access the servlet. | |
</li> | |
<li> | |
To access the servlet, point your web browser at : | |
<blockquote> | |
http://localhost:8080/velexample/servlet/SampleServlet | |
</blockquote> | |
or if that doesn't work : | |
<blockquote> | |
http://<your computer's ip address>:8080/velexample/servlet/SampleServlet | |
</blockquote> | |
</li> | |
<li> | |
You should see the sample output. | |
</li> | |
</ol> | |
<p> | |
<a name="ResinExample"><strong>Caucho Technology's Resin</strong></a> | |
</p> | |
<p> | |
Setting up the example servlet under <a href="http://www.caucho.com">Caucho Technology's Resin</a> | |
servlet engine is also very simple. The following instructions were tested with the version 1.2.5 | |
release. The following assume that you have unzip-ed or untar-ed the distribution, know how to start | |
the servlet engine (something like bin/httpd.sh under unix...), and know where the doc directory is | |
(in the root of the distribution). | |
</p> | |
<ol> | |
<li> | |
Copy the SampleServlet.class file into the doc/WEB-INF/classes directory. | |
</li> | |
<li> | |
Copy the sample.vm template file into the doc/ directory | |
</li> | |
<li> | |
Copy the Velocity jar (and any required dependencies - see note above in | |
Tomcat setup section) into the doc/WEB-INF/lib directory. | |
</li> | |
<li> | |
Start resin. | |
</li> | |
<li> | |
To access the servlet, point your web browser at : | |
<blockquote> | |
http://localhost:8080/servlet/SampleServlet | |
</blockquote> | |
or if that doesn't work : | |
<blockquote> | |
http://<your computer's ip address>:8080/servlet/SampleServlet | |
</blockquote> | |
and you should see the output. | |
</li> | |
</ol> | |
<p> | |
Note that this appeared to be a simpler configuration - with the Tomcat example, | |
you set up a complete, new, separate webapp, whereas the Resin instructions | |
don't, although both should provide a sufficient setup to let you play with | |
Velocity. | |
</p> | |
<p>Note that while we wish we could, we can't answer questions about the servlet | |
engines. Please use the resources provided by the servlet engine provider. | |
</p> | |
<p> | |
<a name="WebLogic"><strong>BEA WebLogic</strong></a> | |
</p> | |
<p> | |
Paw Dybdahl <pdy@csg.csc.dk> contributed <a href="velocity_and_weblogic.html">this</a> | |
description of using Velocity with WebLogic, as well as some good general suggestions and | |
examples for working with servlets. | |
</p> | |
</blockquote> | |
</p> | |
</td></tr> | |
<tr><td><br/></td></tr> | |
</table> | |
</td> | |
</tr> | |
<!-- FOOTER --> | |
<tr><td colspan="2"> | |
<hr noshade="" size="1"/> | |
</td></tr> | |
<tr><td colspan="2"> | |
<div align="center"><font color="#525D76" size="-1"><em> | |
Copyright © 1999-2002, Apache Software Foundation | |
</em></font></div> | |
</td></tr> | |
</table> | |
</body> | |
</html> | |
<!-- end the processing --> | |