Use Velocity and store your template in the filesystem. Velocity is a straightforward templating engine with a lightweight syntax similar to the expression language introduced in Recipe 9.2. The following Velocity template is used to create an email:
#set( $customer = $subscription.customer ) #set( $magazine = $subscription.magazine ) $customer.firstName, Your subscription to ${magazine.title} on $subscription.endDate. If you are interested in renewing your subscription, please click on the following URL, and enter your password: ${magazine.baseUrl}/renew?cust=org.codehaus.cjcook:cjcook-content:jar:0.19
This template references a Subscription
bean bound to the name subscription
. This Subscription
object has a customer
property and a magazine
property, and both of these
properties are assigned to a local template variable using the #set
directive. To render a Velocity template,
the engine is initialized using Velocity.init(
)
, a VelocityContext
is
created and populated, and the template is read with a FileReader
. The following code renders this template:
import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; // Initialize Velocity Velocity.init( ); // Create a context and put our subscription object into the context VelocityContext context = new VelocityContext( ); context.put("subscription", testSubscription( )); // Create a Reader to read our velocity template. Reader reader = new FileReader( new File("renew.vm") ); // Evaluate our template and write the result to a StringWriter StringWriter writer = new StringWriter( ); Velocity.evaluate(context, writer, "test", reader); System.out.println( writer.toString( ) );
The template is loaded from the filesystem in a file named
renew.vm
, and the following output
is printed to the console:
Tim, Your subscription to Science World expires on July 20, 2003. If you are interested in renewing your subscription, please click on the following URL, and enter in your password. http://www.scienceworld.com/renew?cust=22324
In the previous example, Velocity
is used as a singleton—a single
instance of the VelocityEngine
in one Java Virtual Machine. The Velocity engine has a
number of configuration options, but, in this example, the Velocity
engine is configured with a default set of properties through a call to
Velocity.init( )
. The template is
stored on the filesystem, and the template is read using a FileReader
. The output of the template
evaluation is written to a StringWriter
. To merge a template with a context, Velocity.evaluate( )
is passed the following
parameters: a VelocityContext
, a
Writer
to hold the output, a name for
logging purposes, and a Reader to read the template.
Velocity syntax is very simple, and it is similar to the expression language
used in JSP 2.0 EL and Commons JEXL. If you want to print out the value
of a bean property, use ${bean.property}
or ${bean.getProperty( )}
; Velocity can handle
both bean properties and methods. In addition to the basic expression
syntax, Velocity also supports a number of directives and control loops,
which are explored in Recipe
9.7
The one directive used in the previous example is #set
, which assigns a variable for use later
in the script; #set($customer
=
$subscription.customer)
assigns the customer
property of the subscription
object to the variable $customer
. Table 9-3 lists some sample Velocity
references that demonstrate referencing bean properties and invoking
methods.
Table 9-3. Sample Velocity references
Velocity reference |
Evaluates to |
---|---|
|
The value of "sub" in the |
|
The value of |
|
The return type of |
|
If |
|
If |
Velocity has a number of configuration options that allow you to configure logging, character encoding, and the behavior of directives. For more information about configuring Velocity, see "Velocity Configuration Key and Values" in the Velocity Developer's Guide (http://velocity.apache.org/engine/releases/velocity-1.6.1/user-guide.html).