9.6. Using a Simple Templating Language

Problem

You need to produce a parameterized message using a template stored in a file.

Solution

Use Jakarta Velocity and store your template in the filesystem. Jakarta 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=${customer.id}

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

Discussion

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

${sub}

The value of “sub” in the VelocityContext.

${sub.endDate}

The value of sub.getEndDate( ).

${sub.setProp("Val")}

The return type of setProp( ) is void, this reference does not evaluate to a value, but it does invoke the setter with one argument.

$!{customer.firstName}

If customer.getFirstName( ) returns a null reference, this evaluates to an empty String. This is called a quiet reference.

${customer.firstName}

If customer.getFirstName( ) returns a null, this evaluates to the String “null.”

See Also

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://jakarta.apache.org/velocity/developer-guide.html).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.74.66