This page last changed on Dec 14, 2004 by casey.

Overview

In WebWork, the UI tags wrap generic HTML controls while providing tight integration with the core framework. The tags have been designed to minimize the amount of logic in compiled code and delegate the actual rendering of HTML to a template system. Templates can be grouped together and seperated into different Themes. The UI tags attempt to cover the most common scenarios, while providing a Component Tag for creating custom components. The UI tags also provide built-in support for displaying inline error messages.

Templates

WebWork uses the Velocity template system to render the actual HTML output for all UI tags (jsp and velocity). A default implementation of all templates has been included with the core distribution allowing users to use WebWork's UI tags "out of the box". Templates can be edited individually or replaced entirely allowing for complete customization of the resulting HTML output. In addition, the default template can be overridden on a per tag basis allowing for a very fine level of control.

The templates can be found in the distribution package in a directory called template under the src/java directory or in the webwork-x.x.jar file. For template customization, copy the template directory into the root directory of your application or place it in the classpath. Webwork will attempt to load the templates from those two places first. Otherwise, the templates will be loaded from the webwork jar file.
/myApp
      /META-INF
      /WEB-INF
      /template

Inside the template directory, you will find two template sets called Themes (xhtml and simple). The default template set that is used with UI tags is 'xhtml' unless specified by the theme attribute in your UI tag or in the webwork.properties file with the webwork.ui.theme variable. You can modify the pre-existing templates or create your own.

The AbstractUI class is the base class that other UI tags extend. It provides a set of attributes that are common across UI components. The AbstractUI class defines an abstract method:
protected abstract String getTemplateName();

The AbstractUI class will load the template specified by the subclass or optionally, a template specified by the user using the template attribute. The following will load myOwnTextTemplate.vm for the textfield UI tag instead of the built in template text.vm

NOTE: You have to create a template file called myOwnTextTemplate.vm and store it in xhtml for this to work.
<!-- loads /template/xhtml/myOwnTextTemplate.vm -->

<ww:ui textfield label="'mylabel'" name="'myname'" template="'myOwnTextTemplate.vm'" />

otherwise
<!-- loads default /template/xhtml/text.vm -->
<ww:ui textfield label="'mylabel'" name="'myname'" />

Built in templates

The default templates that correspond to each UI tag are as follows:
UI tag default template
checkboxList checkboxlist.vm
checkbox checbox.vm
combobox combobox.vm
component empty.vm
doubleSelect doubleselect.vm
file file.vm
form form.vm(to open)
form-close.vm(to close)
hidden hidden.vm
label label.vm
password password.vm
radio radiomap.vm
select select.vm
submit submit.vm
tabbedpane tabbedpane.vm
textarea textarea.vm
textfield text.vm
token token.vm

Accessing variables

A VelocityContext object is created and used by all WW velocity views with the following context parameters:

  • tag - a reference to the tag object
  • stack - the current OgnlValueStack
  • ognl - a reference to the utility class OgnlTool
  • req - a reference to the HttpServletRequest object
  • res - a reference to the HttpServletResponse
  • webwork - instance of WebWorkUtil
  • action - action associated with the current request/ActionInvocation
  • parameters - map of the current parameters

These variables can be accessed in the template by using $TAG_NAME where TAG_NAME is one of tag, stack, ognl, req, ...). The template file is then processed. A few examples:
NOTE: The bang (!) will print the value if its defined and "" if its not
$!req.requestURI
$!req.method

$!tag.templateDir
$!tag.theme

$!parameters.name
$!parameters

Understanding the Webwork Template System

Look at how the template is found and loaded. A peek into AbstractUITag shows us the string used to build the template:
protected String buildTemplateName(String myTemplate, String myDefaultTemplate) {
        ...
        return "/" + getTemplateDir() + "/" + getTheme() + "/" + template;
}

With the defaults, this will return the string for the textfield UI tag
/template/xhtml/text.vm

Webwork will attempt to find these values before it uses the default ones. You don't have to override any values and can modify the built in templates if you so desire(your choice). Webwork searches for these values in the order they are listed:
  • getTemplateDir()
    • webwork.ui.templateDir value in webwork.properties
    • otherwise, "template" is returned
  • getTheme()
    • in UI tag theme attribute
    • webwork.ui.theme value in webwork.properties
    • otherwise, "xhtml" is returned
  • template
    • in UI tag template attribute
    • otherwise, defaults to specified template

Templates with CSS

The default templates define several properties for use with CSS when HTML is generated from webwork tags. These properties can be found in a stylesheet located in the /template/xhtml directory called styles.css. You can use this stylesheet as a skeleton for your application and build on it or create your own, but remember you must include a link to the stylesheet within your jsp or velocity page.
styles.css:
.label {font-style:italic; }
.errorLabel {font-style:italic; color:red; }
.errorMessage {font-weight:bold; text-align: center; color:red; }
.checkboxLabel {}
.checkboxErrorLabel {color:red; }
.required {color:red;}
.requiredLabel {font-weight:bold; font-style:italic; }

referencing the stylesheet with a link inside your webpage (relative path or you can specify it from the root of your container):
<link rel ="stylesheet" type="text/css" href="/webwork-example/template/xhtml/styles.css" title="Style">

Note: Webwork now has new attributes in the UI tags for more generic support of HTML styles and classes to make the look and feel even more flexible to implement. These are defined respectively as cssStyle and cssClass.

<ui:textfield label="'lebal'" name="'nmae'" cssStyle="'float:left; color:red'" cssClass="'myclass'"   />

Creating Custom Components

At first glance the component tag doesn't look that impressive. The ability to specify a single template and use a number of predetermined attributes looks rather lacking. But the supplied tag offers a number of benefits to developers.

Before diving right into the custom component, first I will identify some advantages to using the component tag to create your components. Then I will detail the two types of error messages in WebWork 2 and how our custom component (for displaying one of these types) fits into the equation. Finally, I will present a sample Action class, Jsp file and template file for our component. When we are finished, you will be able to incorporate the new component into your application.

Why use the component tag?

  • removes the need to develop your own Jsp tag library
  • provides integrated support for accessing the ValueStack
  • leverages XWork's support for internationalization, localization and error handling
  • faster prototyping using templates (editable text files) instead of compiled code
  • re-use and combine existing templates

More on error message support:

In WebWork 2, there are two types of error messages: field error messages and action error messages. Field error messages are used to indicate a problem with a specific control and are displayed inline with the control. A number of tags provide built-in support for displaying these types of messages. Action error messages on the other hand, indicate a problem with executing an action. Many things can go wrong in a web application, especially an application that relies on external resources such as a database, remote web service, or other resource that might not be accessible during the execution of an action. Handling an error gracefully and presenting the user with a useful message can often be the difference in a positive user/customer experience and a bad one.

When these types of errors occur, it is more appropriate to display these messages separate from individual controls on the form. In the example below, we will create a custom component that can be used to display action error messages in a bulletted list. This component can then be used on all your forms to display these error messages.

The action class below was created to handle a promotion on the website: a free e-certificate. It will try to email the certificate, but an exception will be thrown.

Action class:

package example;

import com.opensymphony.xwork.ActionSupport;

public class AddUser extends ActionSupport {

    private String fullname;
    private String email;

    public String execute() throws Exception {
        // we are ignoring field validation in this example

        try {
            MailUtil.sendCertificate(email, fullname);
        } catch (Exception ex) {
            // there was a problem sending the email
            // in a real application, we would also
            // log the exception
            addActionError("We are experiencing a technical problem and have contacted our support staff. " +
                           "Please try again later.");
        }

        if (hasErrors()) {
            return ERROR;
        } else {
            return SUCCESS;
        }
    }

    public String getFullname() {
        return fullname;
    }

    public void setFullname(String fullname) {
        this.fullname = fullname;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

}

Jsp page:

<%@ taglib uri="webwork" prefix="ui" %>

<html>
<head><title>custom component example</title></head>

<!-- don't forget this -->
<link rel ="stylesheet" type="text/css" href="/webwork-example/template/xhtml/styles.css" title="Style">

<body>

<ui:form action="AddUser.action" method="POST">
<table>
    <ui:component template="action-errors.vm" />
    <ui:textfield label="Full Name" name="fullname" />
    <ui:textfield label="Email" name="email" />
    <ui:submit name="submit" value="Send me a free E-Certificate!" />
</table>
</ui:form>

</body>
</html>

HTML output (before submitting):

<html>
<head><title>custom component example</title></head>
<link rel ="stylesheet" type="text/css" href="/webwork-example/template/xhtml/styles.css" title="Style">

<body>

<form  action="AddUser.action" method="POST" />

<table>
    

    <tr>
  <td align="right" valign="top"><span class="label">Full Name:</span></td>
  <td>
<input type="text" name="fullname" value="" />
  </td>
</tr>
    <tr>
  <td align="right" valign="top"><span class="label">Email:</span></td>
  <td>
<input type="text" name="email" value="" />
  </td>
</tr>
    
<tr>
  <td colspan="2">
    <div align="right">
      <input type="submit" name="submit" value="Send me a free E-Certificate!"/>
    </div>
  </td>
</tr>


</table>
</form>

</body>
</html>

The template below will loop through any action errors and display them to the user in a bulletted list.

Template (action-errors.vm)
#set ($actionErrors = $stack.findValue("actionErrors"))

#if ($actionErrors)
<tr>
    <td colspan="2">
        <span class="errorMessage">The following errors occurred:</span>
        <ul>
            #foreach ($actionError in $actionErrors)
            <li><span class="errorMessage">$actionError</span></li>
            #end
        </ul>
    </td>
</tr>
#end

HTML output (after submitting):

<html>
<head><title>custom component example</title></head>
<link rel ="stylesheet" type="text/css" href="/webwork-example/template/xhtml/styles.css" title="Style">

<body>

<form  action="AddUser.action" method="POST" />

<table>
    
<tr>
    <td colspan="2">
        <span class="errorMessage">The following errors occurred:</span>
        <ul>
            <li class="errorMessage">
                We are experiencing a technical problem and have contacted our 
                support staff. Please try again later.
            </li>
        </ul>
    </td>
</tr>

    <tr>
  <td align="right" valign="top"><span class="label">Full Name:</span></td>
  <td>
<input type="text" name="fullname" value="Sample User" />
  </td>
</tr>
    <tr>
  <td align="right" valign="top"><span class="label">Email:</span></td>
  <td>
<input type="text" name="email" value="user@example.com" />
  </td>
</tr>
    
<tr>
  <td colspan="2">
    <div align="right">
      <input type="submit" name="submit" value="Send me a free E-Certificate!"/>
    </div>
  </td>
</tr>


</table>
</form>

</body>
</html>

Document generated by Confluence on Dec 14, 2004 16:36