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.
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.
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
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
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
(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 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
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
<template:put> tag defining the various components.
PutTag -- used as
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
method in the Java GUI. Each
PutTag must give a name to its relevant component.
GetTag -- used as
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.
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:
|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
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.
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.
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.
Copyright © 2009 O'Reilly Media, Inc.