http://www.developer.com/

Back to article

Add Velocity to Your Development


April 30, 2003

What a Template Engine Should Be

In it's simplest form, a template engine takes data, processes it and then displays it. For example, the data found in a company's employee list can be shown in a simple HTML page on the company's intranet or it can be simplied and seen on a salespersons' cellphone while he is on the road. The use of templates is what enables programmers and designers to interact and utilize the data in the most appropriate way. A very good example of what a template engine should be is Velocity.

Velocity is an open-source Java-based template engine. It is part of the Jakarta project and boasts an active community of developers and users. It was initially created as a re-thinking of the WebMacro servlet framework but it has grown to have a variety of non-servlet uses.

Keep it Simple

The beauty of Velocity lies in its simple template syntax and the separation of content and data. It allows programmers to worry just about the code and designers to create the necessary look-and-feel without having to include all sorts of code inside the templates. This is a marked contrast from the traditional JavaServerPages (JSP) and PHP ways of creating pages. In those pages, programming logic is included in the pages and can cause confusion and difficulty in understanding and maintaining the pages. Velocity does this by forcing the use of at least two files, the template and a Java class. A quick example will help illustrate this distinction of data and display.

Putting Velocity to Use

First, we need to download and install Velocity if it isn't already on your computer. 1.3.1 has just been released and the examples in this article will be using that particular version. The released files can be found on Jakarta's server. Once you've downloaded and unpacked either the tarball or zip file, put the velocity-dep-1.3.1.jar in your CLASSPATH. This will allow the examples to be compiled and ran without difficulty.

The usual suffix for a Velocity template is .vm so let's create a file named hellovelocity.vm. This will be a very simple template which, can show if everything is installed correctly, and how Velocity forces the separation of content and presentation. Put the following in the file:

Hello $name, this is Velocity working!
Once you have saved the template, it will be time to open HelloVelocity.java. It's best to put this file in the same directory as the template. Here's the code that shows the Velocity magic:

import java.io.StringWriter;

import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;


public class HelloVelocity
{
    public static void main(String[] args) throws Exception
    {
        /*  first, get and initialize an engine  */
        VelocityEngine engine = new VelocityEngine();
        engine.init();

        /*  next, get the Template  */
        Template template = engine.getTemplate( "hellovelocity.vm" );

        /*  create a context and add data */
        VelocityContext context = new VelocityContext();
        context.put("name", "World");

        /* now render the template into a StringWriter */
        StringWriter writer = new StringWriter();
        template.merge( context, writer );

        /* display the results */
        System.out.println( writer.toString() );    
    }    
}

Once both files are saved and ready, compile the class and run. If all goes according to plan, you should see:

Hello World, this is Velocity working!

A Quick Look at VTL

Let's take a quick walk thru this example. First, the only special part of the template is $name. This is an example of the Velocity Template Language (VTL), which is how Velocity can display dynamic content within text. All Velocity variables begin with a $ in front of the identifier. This identifier maps back to the VelocityContext object which will be discussed a little later. The identifier, name, is replaced by the value found in the VelocityContext object. On a side note, you can also use the more formal notation for variables such as ${name}. This can be very useful in situations where data is being combined without whitespace.

This is just a brief, quick overview of VTL. There are many powerful things in the language such as the ability to iterate over lists, create variables inside of templates and create macros within templates to automate.

Looking at the Java Code

Moving to the Java class, one can see how to create a VelocityEngine object, initialize it and also to create a Template object, which reads in the template file. Once this bootstrapping is done, the VelocityContext object is created and data is inserted into it. VelocityContext uses a HashMap for data storage. The key will always be the same as the identifier from your template and the value can be a String or an object. This last part is where Velocity becomes very powerful since you can store, for example, an Employee object with an identifier of employee and have a template access the data simply as $employee.getName() if that method is public. If you create the Employee objects by accessing data stored in database, Velocity does not need to know about that. All it will care about is the created Employee object. This is a welcome change from a JSP/PHP world.

Though many use Velocity is in a servlet framework, others have found it to be useful in other types of frameworks. Torque is a very good example of a non-servlet use. Torque is a persistence layer that can generate both SQL and Java code based on an XML configuration file. This generation is done thru the use of Velocity templates. These templates are structured in such a way that various databases can be supported quite easily.

Another example is Anakia which many Jakarta projects use to create documentation. Again, using an XML file, Anakia merges that with Velocity templates to create the final documentation. This allows the data found in the XML file to be separate from the display within a template.

Conclusion

Overall, Velocity is well suited for integration with existing setups since any publicly accessible method in an Object can be included in the VelocityContext. This allows Velocity to be used without having to redo any existing work. The separation of the templates and the data can keep an easy peace continuing between programmers and designers since neither will have their toes stepped upon. The Velocity Template Language is easy to pick up but powerful in what it can do, allowing templates to remain simple yet display data in a multitude of ways.

About the Author

Josh Lucas works for CollabNet by day and tries to balance hacking on his own code and playing with his two kids by night.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date