Skin Web applications using Xkins

Add skinning capabilities to your Web application

Page 2 of 2

Next, we start cutting and pasting the HTML from the mock pages to the Xkins templates. After that, we continue doing the same with the frame, the buttons, and the branding. The following code shows a piece of Barnie & Nibble's skin (just the field templates):

<skin name="bn" extends="base">
   <path name="images" url="/images" />
   <element name="spacer" path="images" url="/cleardot.gif"/>

<!-- field templates -->
  <template name="field" group="field">
      <content><![CDATA[

<td width="100%">
<table border=0 cellpadding=0 cellspacing=0 width="100%">
<tr>
$label
</tr>
<tr>
$input
</tr>
</table>
        ]]></content>
   </template>
   <template name="fieldLabel" group="field">
      <content><![CDATA[

 <td WIDTH="25%"><font size="-1" 
      face="arial, helvetica, sans-serif">$label</font></td>
        ]]></content>
   </template>
   <template name="fieldLabelMandatory" group="field">
      <content><![CDATA[
 
 <td WIDTH="25%"><font size="-1" face="arial, helvetica, sans-serif">$label</font></td>
        ]]></content>
   </template>
   <template name="fieldInput" group="field">
      <content><![CDATA[      
<td colspan="$colspan" style="font-family: verdana,arial,helvetica,sans-serif; font-size: x-small;">
   $input <br><b>(Optional)
   </b></td>        ]]></content>
   </template>
   <template name="fieldInputMandatory" group="field">
      <content><![CDATA[      
       <td WIDTH="25%">$input <img src="$res_mandatory" border="0"/></td>        ]]></content>
      <element name="mandatory" path="images" url="/mandatory.gif"/>
   </template>
   <template name="nestedField" group="field">
      <!--
      jsp:bodyContent
      -->
      <content><![CDATA[      
<td colspan="$res_fieldColspan" style="font-family: verdana,arial,helvetica,sans-serif; font-size: x-small;">
$bodyContent
</td>        ]]></content>
   </template>   
<!-- end field templates -->
<!-- The rest of the templates go here -->
</skin>

Use the skins

Now that we have a base skin and both required skins, we can create the JSP pages that will use these skins. To do that, we use the Xkins Forms tags because they use the templates defined in the base skin. You could create your own taglibs to use Xkins just like Xkins Forms does; then you wouldn't need to use Xkins Forms. But, Xkins Forms works fine with the Struts framework, which we use in this application.

We need two pages:

  • index.jsp: Where data entry is performed
  • done.jsp: Where the results print

Our example is just a demo application, so we won't really process the subscription request, just redirect it from index.jsp to done.jsp. In a real application, a process would be completed between these pages.

Notice how Xkins is integrated with Struts in our example application. Xkins's taglibs do not replace Struts taglibs, they just decorate the page. You do not use, for example, the <table> HTML tag, but instead <forms:frame key="frame.title" width="30%"> to contain the form and add skinning capabilities. If your application uses Struts and you want to use Xkins, just place the Xkins Forms taglibs in your pages to decorate them. Then, pass all HTML tags used in your JSP pages to Xkins's templates and let Xkins generate the look and feel.

Though not shown in this example, Tiles can be used with Xkins. Xkins and Tiles can work together without overlapping: let Tiles manage page layout and Xkins render your components.

The following code shows the JSP page that renders the example's form, using Xkins Forms and Struts taglibs:

<html:form action="/subscribe" focus="lastName">
<xkin:template name="branding"/>
<forms:frame key="frame.title" width="30%">
   <forms:row>
      <forms:field key="subscription.name" mandatory="true" >
         <html:text property="name"/>
      </forms:field>
   </forms:row>      
   <forms:row>
      <forms:field key="subscription.email" mandatory="true" >
         <html:text property="email"/>
      </forms:field>
   </forms:row>
   <forms:row>
      <forms:field key="subscription.document" mandatory="true" >
         <html:text property="document"/>
      </forms:field>
   </forms:row>   
   <forms:row>
      <forms:field key="subscription.birthday">
         <html:select property="month">
            <option value="month">Month</option>
         </html:select>
         <html:select property="day">
            <option value="day">Day</option>
         </html:select>
      </forms:field>
   </forms:row>      
   <forms:buttons>
      <forms:button key="button.continue" default="true" onclick="document.subscribeForm.submit();"/>
   </forms:buttons>
</forms:frame>
</html:form>

In our example, we use Struts—which also resolves internationalization—as the UI framework. We use the <xkins:template/> tag to render the branding template at the top of the page and the <forms:*/> tags to render the form. We have a frame that contains multiples rows. Each row has one or more fields. When the frame renders, it asks each row to render itself. And each row asks the field to render. In each case, all these tags use the templates defined in the skin, so just changing the Xkins definition file changes the page's look and feel with no JSP modification.

The buttons tag contains the page buttons, which are passed by parameter to the frame template so you can place the form buttons where the template indicates. Here, we use the button tag to render a button according to the skin. In Amazing's skin, we create a button with images (in a table); in Barnie & Nibble's skin, we use just HTML buttons. Notice also that the JSP page contains no HTML tags or CSS classes: the HTML rendering and styles are delegated to Xkins.

Deploy the Web application

Now that all the pieces are set, you just deploy the war file in a servlet container and start using the demo application. In the example, we integrate Xkins with Struts. You configure the XkinsPlugin in the struts-config.xml file like this:

<struts-config>
<!-- Struts specific configuration goes here -->
   <plug-in className="ar.com.koalas.xkins.struts.XkinsPlugin">
      <set-property property="config" value="/xkins-forms-definition.xml"/>
      <set-property property="autoReload" value="2000"/>      
      <set-property property="skinType" value="base"/>        
   </plug-in>
</struts-config>

Business is expanding!

After successfully implementing our application, a new client, the Box Store, requests our services. The company gives us its application's look and feel, and we develop the skin, as shown in Figure 5.

Figure 5. Box Store skin

This skin differs from the other bookstore skins, and shows how flexible the Xkins framework can be when developing skin-aware user interfaces. Check out this skin in the source code.

Other Xkins usages

Xkins can not only be used to skin a Web application. The Xkins architecture also allows you to:

  • Create images on the fly, where, in each skin, you can create GIFs or Vector Markup Language, if the browser supports it, thereby determining the skin according to browser capabilities.
  • Create different output according to client needs. You can have a skin to create HTML, another to create WML (Wireless Markup Language), and another for XML, determining skin according to the client's device type.
  • Create reports, where, according to the user's preferences, one skin can create a PDF, another CSV, and another HTML.
  • Create different HTML according to the browser type. You could create a skin for IE, another for Netscape, and another for Linux.

In summary, you could use Xkins as a single point for all templates in your application.

Even if you don't need Xkins's capabilities to create pieces of HTML from templates and just want to use CSS and images, you can use Xkins simply for the sake of organizing your files. For example, you can declare image paths, CSS file names, etc., with this Xkins definition:

<xkins>
<skin name="organizer" url="/images">
   <processor type="ar.com.koalas.xkins.processor.VelocityTemplateProcessor"/>
   <path name="images-bg" url="/backgrounds"/>
   <path name="images-icons" url="/icons"/>
   <path name="css" url="/css"/>
   <element name="logoffIcon" path="images-icons" url="/logoff.gif"/>
   <template name="stylesheet">
      <content><![CDATA[           
         <link href="$res_stylesheet" type=text/css rel=stylesheet/>  
      ]]></content>            
      <element name="stylesheet" path="css" url="/formats.css"/>
   </template>
</skin>
</xkins>

In the JSP page, you can use these definitions like this:

<%@ taglib uri="/WEB-INF/tld/xkins.tld" prefix="xkins" %>
<xkins:template name="stylesheet"/>
<table background="<xkins:path name='images-bg'/>/myBg.gif">
<tr>
   <td>
      <img src="<xkins:resource name='logoffIcon'/>"/>
   </td>
</tr>
</table>

As you can see, you can organize your files with Xkins, and, if you change a path or an image name, just changing the Xkins definition is enough.

The future of Xkins: Xkins Faces

As we've seen, Xkins is based on externalizing component renderings from taglibs. This concept matches perfectly with the JavaServer Faces specification. JSF uses renderers to generate HTML (or whatever ML) for its components. Xkins can also be used to create renderers and to add skinning capabilities.

Xkins Faces is an implementation of JSF renderers that use Xkins. The main renderers implement the Decorator pattern for renderers of a JSF implementation. Xkins Faces define a skin type, so third-party vendors could create many skins that feature this same skin type. Thus, if you develop an application with JSF and Xkins Faces, you could download a new skin for your Web application, deploy it, and use it with no changes, since all templates needed by Xkins Faces are defined in the skin type. So in the near future, many skins could be available for download and use in your Web applications, or your users could compose their own skins based on existing ones and use templates directly from the Internet without deploying them.

Guillermo Meyer works as a software engineer for EDS Argentina. He works with Java and is a Sun Certified Programmer for the Java Platform 1.4. He holds a degree in system engineering acquired from Universidad Tecnologica Nacional de Argentina. He is the creator of the Xkins framework.

Learn more about this topic

| 1 2 Page 2