Implementing Templates with Struts
by Vikram Goyal
11/20/2002
Developing portal sites without a framework in place can be a difficult job.
Using templates can reduce the pain and help with sites where the content and
layout can change in the blink of an eye. Struts can help you develop template-based portal sites,
with the Struts Template tags.
The article covers some basic templating ideas in relation to portals, explains
templating support in Struts, and rounds up with a discussion of Struts Template
tags vs. Tiles, another templating mechanism.
Getting Struts
Struts is a Web application framework
that facilitates the development of Web sites using the
MVC
architecture. It provides a set of classes, tag libraries, and interfaces which
can be used as the basis for Web development. Struts is an open source project
and is developed under the Jakarta-Apache forum.
As with all Jakarta projects, Struts can either be downloaded in source code
or binary
format. In this article,we will use Struts 1.1b2. Though not an official release, this beta release contains significant improvements over version 1.0.2.
First, extract the binary format of the file in a directory of your choice. This will
create a main directory called jakarta-struts-1.1-b2. There are only two subdirectories
created under it -- lib and webapps. lib contains all of our libraries, DTDs, and
TLDs (tag library definitions) that need to be in an application's classpath.
webapps contains various .war (Web Archive) files. These are ready-to-install
(and -run) applications that can be dropped in the webapps directory of any servlet
container. We will be using Tomcat as
our servlet container.
|
Bug fix for .war
We will use struts-blank.war as the basis of our application. This
.war file contains all of the basic libraries and files required to start working
with Struts. However, Struts 1.1 Beta 2 contains a faulty implementation
of this blank .war file and you need to download the correct one
here. Make sure you use this blank .war file for all examples in
this article, and not the blank .war file that gets unzipped with the download
from Struts 1.1-b2. In fact, you can download just this correct blank .war file
and skip downloading the whole Struts 1.1b2, as this download
itself contains all we need.
|
Templating Basics
A template is one thing from which you can make many. Templates help us encapsulate the things
that change and avoid replicating work that's already been done. This
is true for Web applications as well.
With most Web applications, the one thing that keeps changing is
the content. With JSP, it is easy to manage changes to content because JSP, by
default, provides a mechanism to include other files -- the <jsp:include>
tag. Thus a standard page can change its content by changing the included file(s).
But what about the layout? What happens when we need to change not only the
content but also some aspects of the layout? We will answer these questions a little
later.
It helps to visualize templating basics in terms of Java's layout mechanism.
To design GUI applications, Java provides the concept of layout managers, components,
and containers.
Components get placed on containers, while the layout manager
decides how to lay out the containers. Furthermore, containers themselves
can be regarded as components for other containers, thus providing for nesting
behavior. In simple terms, a template for a Web application is a simple JSP
file and is the equivalent of a layout manager. A template hides how the layout
of a Web page is done. In other words, it hides the algorithm for the layout.
If the algorithm needs to change, the change is restricted to the template.
The Web pages implementing this template simply update themselves to reflect
this change.
If templates are the equivalent of layout managers, what are the corresponding
comparisons for containers and components? Components are the actual content files:
the JSP, the HTML, the images, etc. Containers collect these visible components
into one unit. A container itself will be a JSP file. A container needs
to know what template to use to render the components that it contains. To use
a Java GUI, Web example, a panel (container, collecting unit)
can contain buttons and textfields (components, content) and have a GridLayout
(layout manager, template) telling it how to lay out these components.
Now we are in a better position to answer the questions that were raised earlier.
Having learned that a template encapsulates the layout algorithm, we now know
that to change a layout, we only need to change the template. This change will
change the layout of the associated Web pages, without having to change the
Web pages themselves. In portal applications, this can mean significant time
savings when a multitude of pages use the same layout.
Struts Template Support
Struts introduced template support in version 1.0.2. This template mechanism
is based on the one David M. Geary described in his book Advanced JavaServer Pages.
Templates in Struts are implemented using three template tags.
InsertTag -- used as <template:insert>.
Use this tag in the container/collecting unit file. It defines the template that this container will use. Similar to container.setLayout(layout) method in Java GUI, it will be followed by
the <template:put> tag defining the various components.
PutTag -- used as <template:put>.
Use this tag in the container/collecting
unit file. It is used to define the various components/content that make up
this container/collecting unit. It's sort of similar to the container.add(component)
method in the Java GUI. Each PutTag must give a name to its relevant component.
GetTag -- used as <template:get>.
Use this tag in the template file. It tells the template the names of various components defined by the PutTag. It's sort of similar to layout.addLayoutComponent(componentName, component) in the Java GUI.
A Simple Example
You can download the finished example files. We will develop two sets of content files, container (collecting unit) files,
and templates. Once we have these files, we can interchange the templates between
them, validating the idea of minimizing layout changes.
Copy the Struts-blank.war to Tomcat's webapps directory and rename it as
template-example.war.
Restart Tomcat. A new template-example Web application will be auto-deployed
by Tomcat. Delete the directory pages and the file index.jsp. They
are not relevant to this discussion.
Let us start by defining our content files. Create a directory called content
in the template-example directory and create six files in it: top1.htm,
top2.htm, bottom1.htm, bottom2.htm,
middle1.jsp, and middle2.jsp.
What you put in these content files is up to you, but for starters, the static
.htm files simply say what they are. For example, top1.htm contains the following:
This is the <b>TOP</b> Content for the <b>First</b>
example. This is a static html file.
Similarly, the middle1.jsp contains the following:
This is the <b>MIDDLE</b> Content for the <b>First</b>
example. This is a dynamic JSP file and the
current date and time is <%= new Date() %>
Having defined the content, let's define our two templates.
Create a directory called templates in the template-example directory.
Again, create two files, template1.jsp and template2.jsp.
These templates define two different layouts, as shown in the following figures.
 |
 |
| Figure 1, Template 1 |
Figure 2, Template 2
|
To implement these two templates, we define them as follows:
<%@ taglib uri='/WEB-INF/struts-
template.tld' prefix='template' %>
<html>
<head>
<title><template:get name='title'/>
</title>
</head>
<body>
<table border=1>
<tr>
<td><template:get name='top'/></td>
</tr>
<tr>
<td bgcolor="#FF55FF">
<template:get name='middle'/></td>
</tr>
<tr>
<td><template:get name='bottom'/></td>
</tr>
</table>
</body>
</html>
|
<%@ taglib uri='/WEB-INF/struts-
template.tld' prefix='template' %>
<html>
<head>
<title><template:get name='title'/>
</title>
</head>
<body>
<table border=1>
<tr>
<td><template:get name='top'/></td>
<td bgcolor="#FF55FF">
<template:get name='middle'/></td>
<td><template:get name='bottom'/></td>
</tr>
</table>
</body>
</html>
|
| Defining Template 1 |
Defining Template 2 |
Note that these two templates define two different kinds of layouts. In other
words, they define two different layout algorithms.
We have our content and we have our templates. Now we need the container files. Create two container files, called container1.jsp
and container2.jsp, in the root (tomcat-example)
directory. Recall that a container file needs to contain our components (content).
Also, the container file uses the template insert and put tags to define the
template being used and to add components (content), respectively. With these
things in mind, let's look at one of our container files (container1.jsp):
<%@ taglib uri='/WEB-INF/struts-template.tld' prefix='template' %>
<template:insert template='/templates/template1.jsp'>
<template:put name='title' content='Templates' direct='true'/>
<template:put name='top' content='/content/top1.htm' />
<template:put name='middle' content='/content/middle1.jsp' />
<template:put name='bottom' content='/content/bottom1.htm'/>
</template:insert>
To see all this in action, open up your browser and point it to
http://localhost:8080/template-example/container1.jsp.
You should see the following:

Behind the scenes, container1.jsp has used the template template1.jsp to define
the layout of the output page and included content from the different contents.
Notice the use of the attribute direct in <template:put name='title'
content='Templates' direct='true'/>. When direct is set to true, the
content specified by the content attribute is used directly. It is not looked
up in an external file.
Container2 is similar, except that it uses template2 and therefore looks like
this:

The advantage of what we have done so far should be apparent. For
example, we can replace template1 with template2 (simply copy and paste from
template1.jsp
to template2.jsp) and container1.jsp will suddenly look like the following.
We have changed the layout of our container, without having to touch container1
at all! This is the power of templating.

Struts Template vs. Tiles
In version 1.1 of Struts, a templating mechanism known as Tiles was introduced, and since then
has become a major branch. The Tiles mechanism is defined on the Tiles Web site, and is compatible with the Template tags as defined in Struts. In fact, Tiles
is a sort of superset of the Template tags. So why would you use Tiles instead
of Templates?
Tiles allows greater control over our containers (collecting units) by allowing
us to pass parameters. This is quite useful when we want to make our templates
and containers dynamic. Furthermore, Tiles integrates well with Struts action
components.
However, using Tiles can greatly increase the complexity of your code, and significant
time needs to be spent in trying to understand Tiles itself.
Conclusion
Using templates can make your Web applications easy to maintain. This article
has provided a starting ground for understanding templating with Struts. There
are few more things about Templates that you can explore on your own from here, such as
role-based and optional content.
I hope this article encourages you to explore these features.
Vikram Goyal
is the author of Pro Java ME MMAPI.
Return to ONJava.com.