Page 2 of 5
Template engines solve the problem of inserting dynamic content into a text message. Instead of embedding your message code into your program, you create a simple text file that contains the text content. A template engine parses that text file, called a text template, and any dynamic content is inserted with the help of simple template directives. The Jakarta Project's Velocity is my template engine of choice, but you can use one of the many other available engines. Velocity and WebMacro are probably the two most feature-rich and popular engines out there. Both are freely available under open source licenses.
Although I use Velocity in my examples, you should be able to easily port the examples to a different template engine by adopting the relevant engine's syntax.
Let's look at the email example I completed using Velocity. You need to download Velocity and add it to your classpath for the example to compile and run. You also need JavaMail if you want the email to work.
for (int i=0; i<customers.size(); i++)
{
Customer customer = (Customer)customers.get(i);
// Create a context and add all the objects
VelocityContext context = new VelocityContext();
context.put ("lastname",customer.getLastName());
context.put ("total", new Double (customer.getAccountTotal()));
context.put ("customer", customer );
// Render the template for the context into a string
StringWriter message = new StringWriter();
template.merge(context, message);
// Send Email
mm.sendMail (customer.getFirstName(), customer.getEmail(), "Account", message.toString());
}
First, you must understand the Java source code above. Instead of generating text as the first example did, the class above
renders a text file called a Velocity template and emails the result to its recipient. A Velocity template can be any text file, but normally it contains some directives
to insert dynamic content. The most interesting part of the Java code is the Velocity context. The Velocity context provides the link between your Java code and the Velocity text template, which another person could
write. Any object added to the context is available to the template by the name given in the put() method's first parameter. To illustrate how that works, here is the template file:
Dear Mr/Mrs $lastname The total of your account statement is $total Regards Widgets and Gadgets Inc.
When Velocity renders a template, it echoes all the text in the file except for the text that starts with $. A dollar sign indicates a location where a value from an object added to the context should be placed in the template's
rendered output. Because I have context.put("name",customer.getName()) in the Java class, when the template renders, the customer's name replaces any call to $name. The output of the added object's toString() method replaces the Velocity variables (those beginning with $).
One of the most powerful and frequently used features of a template engine is its ability to discover object information using
a built-in reflection engine. The engine allows you to retrieve the value of any public method or any object's data member
added to the context with a convenient Java-like dot notation. The engine also provides another improvement: a shorthand for
JavaBean properties. When using objects with JavaBean properties, you can omit the get part of the method and the trailing brackets. (For complete details check the documentation of your favorite template engine.)
See the template below for an example. Because I added the Customer object to the context in the previous example's Java code, I can rewrite the template like this: