Lets start off with a simple Velocity Screen to get things rolling
so you can see how powerful things are. You should compile this class into
your WEB-INF/classes directory.
 |
 |
 |
 |
// Velocity Stuff
import org.apache.velocity.context.Context;
// Turbine Stuff
import org.apache.turbine.util.RunData;
import org.apache.turbine.modules.screens.VelocityScreen;
public class HelloWorld extends VelocityScreen
{
public void doBuildTemplate( RunData data, Context context )
throws Exception
{
// the context object has already been setup for you!
context.put ("hello", "this is a test...");
}
}
|
 |
 |
 |
 |
Ok, as you can see, you do not even need to return a value from your method!
You simply stuff objects into the Velocity Context and that is it! Next,
you will want to create a .vm template of the same name as your class:
HelloWorld.vm...within that template you will put the BODY portion of your
page. In other words, there is no reason to put the header/footer into
this file since that will be built seperately (more documentation on that
futher down...). You should save this document in your templates/screens/
directory.
 |
 |
 |
 |
<p>
<font color="red">
$hello of the emergency broadcast station.
</font>
</p>
|
 |
 |
 |
 |
When you request a URL like this:
http://www.server.com/servlet/Turbine/template/HelloWorld.vm
What that will do is cause the system to first execute the HelloWold.java
class (if it exists) and then it will call Velocity's template engine directly
and execute the HelloWorld.vm template and then return the results back
to you.
NOTE: Turbine capitalizes the first letter in the class file name
before looking for the matching class in the classpath. This allows you to
follow (somewhat) normal class naming guidelines. For example:
index.vm and Index.vm both map to Index.class
roleeditor.vm maps to Roleeditor.class
role_editor.vm maps to Role_editor.class
The result will be a fully formed HTML document with the $hello
replaced with the value: "this is a test...". If you want to make the URI
above shorter or easier to read, you could simply re-write things using
mod_rewrite.
For example, by removing the "/servlet/Turbine/template" portion
of the URI.
As you can see, this is much easier than doing servlet after servlet
because it removes a lot of the setup and other things that could potentially
go wrong. It also makes the individual template files easier to manage
and more re-usable because there isn't any surrounding page layout mixed
in with the page.
If you want to do something that is more complicated than this that
is reflected across all of your Screens, then you should write a class
that is a subclass of VelocityScreen and then put your specific code
in there. For example, if you wanted a security method to be called automaticially
without having to normally call super() to get it from an overridden method
in the superclass, you could have something like this (semi-pseudo untested
code):
 |
 |
 |
 |
// Velocity Stuff
import org.apache.velocity.context.Context;
// Turbine Stuff
import org.apache.turbine.util.RunData;
import org.apache.turbine.modules.screens.VelocityScreen;
public abstract class SecureScreen extends VelocityScreen
{
protected boolean doCheckSecurity(RunData data)
throws Exception
{
if (data.isSecure())
return true;
else
return false;
}
/*
* override the doBuild() method of the
* TemplateScreen to always check security first
*/
public void doBuild(RunData data, Context context) throws Exception
{
if ( !this.doCheckSecurity(data))
{
// set the template and screen to be different or do
// some other short circuit code here
}
doBuildTemplate(data, context);
return super.buildTemplate(data, context);
}
}
|
 |
 |
 |
 |
What this would do is override the doBuild() method in TemplateScreen (which
is the base class that VelocityScreen subclasses from) and have it
always do a security check before displaying the content. The benefit of
this is that all you need to do to add security to your screen is to simply
subclass this class instead of VelocityScreen. There is also no need
to remember to call super() since the doBuild() method will be called for
you automaticially by Turbine. You can start to see how Turbine is simply
an extension of the servlet framework itself. For example, the Servlet
Engine will call HttpServlet's service() method for you, just like Turbine
will call your doBuild() method for you. Tight integration with tools like
Velocity just make things even cleaner. :-)
One other feature in this system is that if you are not building up
a Context object that is specific for your screen, then you do not need
to create a Java class to match the template file. You simply create the
.vm template and put it in a directory and call it with the same URI described
above. This is really useful when you have a static site of content that
you are converting to be dynamic and you only want to do small portions
of it at any one time. You can also do the opposite of this which is to
only create a Java class file and no template file. You can do this by
simply overriding the doBuild() method in TemplateScreen and returning
your results directly instead of attempting to build a template. Later,
when you want to add a template and remove the HTML code, you can change
the doBuild() into a doBuildTemplate(), build the Context object up and
you are done. Cool!
Here is an example of having templates in subdirectories and making
links to each of them.
Create a directory structure like this:
WEB-INF/templates/screens/admin/
Put index.vm into the screens/ directory.
Put UserAdmin.vm into the screens/admin/ directory.
In index.vm, if you want to link to UserAdmin.vm, you would add something
like this to the HTML:
 |
 |
 |
 |
<a href="$link.setPage("admin,UserAdmin.vm")">User Admin Screen</a>
|
 |
 |
 |
 |
As you can see above, I used a "," instead of a "/". You can use either
one here. The above will create a fully formed URI with the session information
encoded into the link if the clients brower has cookies turned off.