Velocity is a Java-based template engine. It permits web page designers to reference methods defined in Java code. Web designers can work in parallel with Java programmers to develop web sites according to the Model-View-Controller (MVC) model, meaning that web page designers can focus solely on creating a well-designed site, and programmers can focus solely on writing top-notch code. Velocity separates Java code from the web pages, making the web site more maintainable over the long run and providing a viable alternative to Java Server Pages (JSP) or PHP.
Jetspeed has a Velocity templating service built directly into the Jetspeed engine. Many of the controls and controllers are Velocity-driven to create the layout of the portal. You can also base your portlets on Velocity. This means that your portlets will also follow the MVC design pattern, separating content from code.
The examples in tutorials 5 and 6 were useful for you to learn the Portlet interface. However, overriding the getContent method of the portlet interface is not good practice. We recommend abstracting the content generation phase by basing your portlets on one of the MVC-based portlets provided in the Jetspeed distribution; such as JSPPortlet, XSLTPortlet, RSSPortlet, HTMLPortlet or of course the VelocityPortlet.
A Velocity portlet is made up of the typical MVC components:
|MVC Component||Velocity Component|
|Model||Java Objects put in the context|
|Controller||Your Velocity Action|
The controller is your Velocity Action class. The base VelocityPortlet class should rarely have to be modified. Your view is a Velocity template, which will generate the content of your portlet by pulling out dynamic model information from the Velocity context. The getContent method of the VelocityPortlet should never be edited. All content is generated by the template, as designed in our MVC design pattern.
The Life Cycle phases of a portlet are also enhanced with the Velocity portlet.
|ProcessAction||Velocity Action and Action Events|
|Render||Template is called by Velocity Portlet|
Velocity portlets are really about dynamic content. If you have static content, there is no real benefit to using a Velocity portlet; take a look at one of the static content generation portlets such as the HTMLPortlet instead. The basic function of Velocity is really very simple, it substitutes live Java objects into a Velocity template. There is an online tutorial with great examples here.
Let's look at simple introductory example, but we recommend visiting the Velocity site and investing some time in their well-written tutorials.
<HTML> <BODY> Hello $customer.Name! <br/> Here is a list of your current subscriptions:<br/><br/> <table> #foreach( $subscription in $subscriptions ) #if ( $customer.isSubscribed($subscription) ) <tr> <td> $subscription.Name </td> </tr> #end #end </table> </BODY> </HTML>
This example is not included with the examples source code distribution.
The above is an example Velocity template that displays all subscriptions for a given customer. There are two dynamic model objects that we are working with: the customer and subscriptions. Velocity uses a very simple syntax for model variables, simply prefix the variable with a $ sign. The designer can then access all public methods and accessors of that Java object. Velocity uses Java reflection to find the methods. Thus in our example above, the customer object has a getter and setter for the Name attribute. You don't need to specify the get prefix, Velocity will figure it out.
Velocity provides a small set of directives for logic control. Most commonly used are #if and #foreach. #foreach will iterate over any Java 2 collection or array. The #if statement above calls a public method to check if the customer is subscribed to a subscription. Finally, the subscription name is displayed in a table column by getting the Name attribute.
So where did these two variables ($customer, $subscriptions) come from?
They came from your action class. We will look into how to program an action class in more detail later in this section. Right now it's important to understand that your action class puts your model objects into a Velocity construct called the 'context'. The context is where all variables are made accessible to a template. The context is the common liaison between your model and view. Here is how the Java code would put an object into the context:
Customer customer = CustomerPeer.retrieveByPK(primaryKey); context.put("customer", customer); List subscriptions = SubscriptionPeer.doSelect(criteria); context.put("subscriptions", subscriptions);
There is another tutorial on Velocity at Java World. Now that we have a basic understanding of the Velocity context and templates, let's get back to the Velocity Portlet. The MVC components are all configured in the portlet registry.