OpenTranqueraFramework SourceForge.net Logo


Home | Download | Powered by SourceForge.net

Welcome to Xkins home page.

Xkins is a framework that manages skins for your web application.

Skins are used for a web application to look in a different way without the need to write one page for each skin or using CSS. A skin not only manages colors, fonts and images, but also layout and morphology of the web page.

In early Java-Server-Side days, you used to put HTML hardcoded in a Servlet. Then, JSP came to allow you to put your HTML outside Java code. Nowadays, the same happens with taglibs that have HTML tags hardcoded in Java code. Using Xkins you can put this HTML outside your code with an additional and powerful feature: Skins.

Xkins stands from eXtendable Skins. You can define as many skins as you like, and each skin can extend other skin, so it can use all its parent's components and override what it needs to look in a different way. With this feature, maintaining multiple skins becomes a simpler task.

Xkins framework uses Velocity to process snippets of HTML, but you can use any other template processor (Xkins comes with it's own default processor). Xkins also comes with Forms Tag Libs, that allows you to create forms using Xkins and comes with four Skins. Xkins Forms integrates with Struts framework.

Xkins also fits perfect in JSF world, playing a role as a RenderKit, and can work with other presentation frameworks, Struts-Layout.

You can download Xkins framework from SourceForge.net.

Xkins usages and features

Xkins is written in Java and is intended to be used in a J2EE application, but you can use it in other java environments like Desktop or J2ME applications. It is not mandatory to be used in a web environment, as you can use it in an EJB to get XML or other input data that can be externalized to xkins.

In a web environment, Xkins components can be used through its own tag libs, Xkins forms tags, or with your custom tags using the API. You can also integrate Xkins with other presentation frameworks like Struts-Layout or use along with Velocity extending VelocityServlet.

This framework can be extended in order to use templates of any kind. You can implement your own template processor to generate output for your template. Xkins has its own template language that allows you to produce HTML, and has an implementation of a template processor that uses Velocity templates. But you are not restricted to generate HTML or text, but also you could produce PDF, XLS, images on the fly, etc.

Xkins can also be used with JavaServerFaces, implementing a RenderKit that generates HTML or XML with Xkins.

You can use Xkins as a single access point for multiples template processors and add each one Xkin's capabilities in managing different Skins.

Features

  • Web application Skin management
  • Integration with other frameworks (JSF, Struts, Velocity, Struts-layout, etc)
  • An extensible framework that will allow you to write your own template processor according to your needs.
  • Skins can be extended, and override elements, templates or paths, so minimizing maintenance.
  • Allows you to organize UI in elements, templates, paths and Skins.
  • Skin Components can be packaged in a single file and then unziped and loaded in the target web application.
  • Autoreaload feature will reload all skins when you change a definition file.
  • Xkins Forms: A taglib set to use Xkins inmediatly, with Struts 1.1 integration.
  • An API is being defined for Xkins Editors, so you can create an IDE or a Plugin for editing Xkins.

Xkins definition / Skin Components

Xkins are defined in a XML file. If used in a web application, you must declare this file in XkinsServlet declaration in web.xml file. You can declare multiples xkins-definition files where each file will aggregate to the Skins definition.
If you are not using a web application, you can load skins definition from a xkins-definition file without using a servlet.
You can also use Xkins Struts 1.1 plugin in order to load xkins-definition in Struts 1.1 fashion.

In development, you can enable Xkins autoreload feature. So, when you change a Xkin definition file or a template file, Xkins will be reloaded automatically and XkinsLoadEvent will be fired.

You can define all skin information in xkins-definition file or you can declare a Skin Component and pack all Skin data (templates, image files, CSS files, etc) in a single Skin directory. This is done by providing a definition attribute to the Skin declaration.

For example, a Skin named "invierno" can be declared like this:
<xkins>
   <skin name="invierno" url="/skins/forms/invierno" definition="/definition.xml"/>
</xkins>

and this skin directory would have the following directory structure:

You could pack all skin data in a zip file and distribute as a Skin Component (this structure, css files, definition.xml file containing templates, and image files).

A Skin is defined with the following entities:

Skin: This is the definition of the skin, and can contain elements, constants, templates and paths. All Skin definition can be externalized in a file located in Skin path, so creating a Skin Component. Skin has a path relative to context path, where skin's files should be stored (images, sounds, css, etc.). You can also define a specific template processor to be used in the skin, overriding default behavior. This skin can extend other skin, and can override all its parent's components, fully or partially (you can override template's content or just its elements).

Path: Is contained in a Skin and defines a URI relative to Skin's path. You can also define a path not to be relative to skin's path, for instance, to point to a different URI in your context path. Paths are available to be used by all resources in the Skin and Skin's children and are useful to organize your Skin's file's directories.

Processor: With this tag you can define a specific template processor overriding default one. If you create your own template processor and write template's content with your own "language", you must declare your processor's class name with this tag.

Template: Defines a piece of your application User Interface (snippet). Templates are contained by a Skin and have a content, elements and constants. You can define a specific template processor in a template, overriding default behavior. It is very important to define templates properly to minimize maintenance and improve reusability.

Content: It's included into a template tag and declares the template content. Content is XML CDATA so you can use any type of markup language. You can put HTML in content and use parameters and resources to be interpreted by the template processor. If you use Velocity, this is the place where Velocity templates are defined. You can also put Content in individual files and use the url attribute to point to that file. Content can use elements, constants and parameters to generate dynamic content, but it can also be static to generate static content.

Element: This is a resource like an image, a css, a flash, wav, etc. It can be used by templates or from outside a template environment. Defining elements helps you to organize you skin's files and easily change them without impact over templates. Elements can be defined al Skin level (visibility from all skin's templates) or at Template level (visibility only from the template). Element uses skin's paths and adds a URI for the element. So, element's URI is composed by Skin's URI, Path's URI and element's URI.

Constant: This is the other resource type and, like Element, can be defined al Skin level or template level and can be used from templates or from outside a template. The difference with elements is that constants do not use paths and are intended to be used to declare fixed values like colors, font type, etc. that can be overridden from other skins to change template appearence.

Examples

This is a simple example using only Xkins. This means that this examples do not use Velocity, Struts or Xkins Forms. This example is just for show you how Xkins resources, paths and extensibility between Skins work. Xkin Components are show in Xkins Forms example

web.xml declaration

First, you must declare Xkins servlet in order to load Xkins. Xkins are loaded to ServletContext, so they are accesed from XkinProcessor facade.

	<servlet>
		<servlet-name>xkins</servlet-name>
		<servlet-class>net.sf.opentranquera.xkins.core.XkinsServlet</servlet-class>
		<init-param>
			<param-name>config</param-name>
			<param-value>/xkins-forms-definition.xml</param-value>
		</init-param>
		<init-param>
			<param-name>debug</param-name>
			<param-value>8</param-value>
		</init-param>
		<init-param>
			<param-name>detail</param-name>
			<param-value>8</param-value>
		</init-param>
		<init-param>
			<param-name>defaultSkinName</param-name>
			<param-value>invierno</param-value>
		</init-param>
		<init-param>
			<param-name>autoReload</param-name>
			<param-value>3000</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
Here we declare a default skin (invierno), configures configuration file and tell Xkins to monitor our definition changes in order to reload them automatically when they change.

You can also define a listener and context properties in order to start Xkins engine:


	<context-param>
		<param-name>xkins.config</param-name>
		<param-value>/WEB-INF/xkins-faces-definition.xml</param-value>
	</context-param>
	<context-param>
		<param-name>xkins.autoReload</param-name>
		<param-value>1000</param-value>
	</context-param>
	<context-param>
		<param-name>xkins.loader</param-name>
		<param-value>
			net.sf.opentranquera.xkins.core.loaders.XkinsXMLLoader
		</param-value>
	</context-param>		
	<listener>
		<listener-class>
			net.sf.opentranquera.xkins.core.loaders.XkinsLoaderServletContextListener
		</listener-class>
	</listener>		


Xkins-definition file:

This is a piece of a xkin-definition file we will use in our examples, where we are declaring 2 skins: skin1 and skin2:
<?xml version="1.0" encoding="UTF-8"?>
<xkins>
       <!-- SKIN #1 -->
       <skin name="skin1" url="/skins/skin1">
             <processor type="net.sf.opentranquera.xkins.processor.core.TemplateProcessorImpl"/>
             <path name="backgrounds" url="/backgrounds"/>
             <element name="back" path="backgrounds" url="/bg.gif"/>
             <constant name="tipoLetra" value="Arial"/>
				<constant name="colorLetra" value="       #FEDCBA"/>
             <template name="frame">
                    <content><![CDATA[
<table border="0" cellspacing="0" cellpadding="0" background="${res:back}" width="${pro:width}">
<tr><td colspan="5" bgcolor="${res:colorTabla}" 
align="${res:alignTitle}"><font face="${res:tipoLetra}" 
color="${res:colorLetra}"><b> ${pro:title}</b></font></td></tr>
${jsp:bodyContent}
<tr><td colspan="4" bgcolor="${res:colorTabla}" 
align="right"><table border="0" cellspacing="0" 
cellpadding="0"><tr><td height="3"></td></tr>
<tr>${pro:buttons}</tr><tr><td height="3">
</td></tr></table></td>
<td bgcolor="${res:colorTabla}" align="right"> </td>
</tr>
</table>
<script>
document.forms[0].elements[0].focus();
</script>
             ]]></content>
                    <constant name="colorTabla" value="red"/>
                    <constant name="alignTitle" value="center"/>
             </template>
             <template name="field">
                    <content><![CDATA[
<tr>
<td aligh="right"><img src="${res:icon}"></img>
</td><td><font face="${res:tipoLetra}" 
color="${res:colorLetra}">${pro:label}<</font></td><td>
 </td><td>${pro:data}</td><td> </td>
</tr>
<tr><td colspan="5"> </td></tr>
             ]]></content>
                    <element name="icon" path="backgrounds" url="/bullet.gif"/>
             </template>
             <template name="button">
                    <content><![CDATA[
<td>
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td background="${res:bgBoton}">
<style>
a:link{text-decoration: none}
a:visited{text-decoration: none}
a:hover {text-decoration: none }
</style>
<a href="${pro:action}" style>
<font face="${res:tipoLetraBoton}" 
color="${res:colorLetraBoton}"> ${jsp:bodyContent} </font>
</a>
</td>
<td> </td>
</tr>
</table>
</td>
             ]]></content>
                    <element name="bgBoton" path="backgrounds" url="/bg.gif"/>
                    <constant name="tipoLetraBoton" value="Arial"/>
                    <constant name="colorLetraBoton" value="    #FEDCBA"/>
             </template>
       </skin>
       <!-- SKIN #2-->
       <skin name="skin2" url="/skins/skin2" extends="skin1">
             <element name="back" path="backgrounds" url="/back.gif"/>
             <constant name="tipoLetra" value="Courier"/>
             <constant name="colorLetra" value="       #00FF00"/>
             <template name="frame">
                    <constant name="colorTabla" value="blue"/>
                    <constant name="alignTitle" value="right"/>
             </template>
             <template name="field">
                    <content><![CDATA[
<tr>
<td aligh="right"><img src="${res:icon}"></img>
</td><td><font face="${res:tipoLetra}" 
color="${res:colorLetra}">${pro:label}</font></td>
<td colspan="3"> </td>
</tr>
<tr>
<td> </td><td>${pro:data}</td><td colspan="3"> </td>
</tr>
             ]]></content>
             </template>
             <template name="button">
                    <element name="bgBoton" path="backgrounds" url="/back.gif"/>
                    <constant name="tipoLetraBoton" value="Courier"/>
                    <constant name="colorLetraBoton" value="    #00FF00"/>
             </template>
       </skin>
</xkins>

In this example, Skin2 extends Skin1.
Skin1 declares 3 templates: frame, field and button.
Skin2 overwrites resources "back", "tipoLetra" and "colorLetra", frame's resources, field template content and buttons resources.

JSP file:

These skins can be used in JSP in the following way:

<%@page contentType="text/html"%>
<%@ taglib uri="/WEB-INF/tld/xkins.tld" prefix="xkin" %>
<%@ page import="net.sf.opentranquera.xkins.core.*" %>
<%
//skin change on reload
String skin=XkinProcessor.getCurrentSkinName(request);
if(skin.equals("skin1")) {
    skin="skin2";
} else {
    skin="skin1";
}
XkinProcessor.setCurrentSkinName(request, skin);
%>
<html>
<head><title>Skin: <xkin:xkinName/></title></head>
<body>
<center>
<form>
<xkin:template name="frame">
    <xkin:templateParameter name="width">40%</xkin:templateParameter>
    <xkin:templateParameter name="title">Xkins Demo</xkin:templateParameter>
    <xkin:templateParameter name="buttons">
        <xkin:template name="button">
            OK
            <xkin:templateParameter name="action">
            	javascript:alert('OK');
            </xkin:templateParameter>
        </xkin:template>
        <xkin:template name="button">
            Change Skin
            <xkin:templateParameter name="action">
            	javascript:top.location.reload();
            </xkin:templateParameter>
        </xkin:template>
    </xkin:templateParameter>
    <xkin:template name="field">
        <xkin:templateParameter name="label">
            First name
        </xkin:templateParameter>
        <xkin:templateParameter name="data">
            <input type="text" name="nombre">
        </xkin:templateParameter>
    </xkin:template>
    <xkin:template name="field">
        <xkin:templateParameter name="label">
            Last name
        </xkin:templateParameter>
        <xkin:templateParameter name="data">
            <input type="text" name="apellido">
        </xkin:templateParameter>
    </xkin:template>
    <xkin:template name="field">
        <xkin:templateParameter name="label">
            Phone
        </xkin:templateParameter>
        <xkin:templateParameter name="data">
            <input type="text" name="telefono">
        </xkin:templateParameter>
    </xkin:template>
    <xkin:template name="field">
        <xkin:templateParameter name="label">
            e-mail
        </xkin:templateParameter>
        <xkin:templateParameter name="data">
            <input type="text" name="email">
        </xkin:templateParameter>
    </xkin:template>
</xkin:template>
</form>
</center>
<jsp:include page="../footer.jsp"/>
</body>
</html>

By using template tag, it commands the Processor to use each template. TemplateParameter tag is used to pass a parameter for the template. The bodyContent built-in parameter is passed through template tag body content.
In runtime, if skin name is set to "skin1", generated HTML by this JSP page would be:

In runtime, session attribute defined in Skin.ATTR_SKIN_NAME is used to determine skin name. Login will be responsible to set this attribute properly according to user?s preferences. If no vaule is set, default skin name is assumed. Default skin name can be declared as an init parameter in web.xml XkinServlet declaration.
If skin name is "skin2", the generated HTML would be:

Using Xkins in this way is posible but a little confussing, so it's better to write your own tags to clarify Xkins usage, or you can use Xkins Forms Tags or JSF integration.

Xkins taglibs

Xkins has some utility taglibs. We have seen an example of such taglibs in example using:

  • TemplateTag
  • TemplateParameterTags.

But there are some more tags that you can use to access Xkin's resources, paths, and other useful things:

PathTag:

This tag is used to access paths from Skins definitions.

Example:
<xkin:path name="backgrounds"/>

Will produce this output (assuming skin1 set in session) : /xkins/skins/skin1/backgrounds

ResourceTag

You can access Skin resources with this tag.

Example:
<xkin:resource name="back"/>
<xkin:resource name="tipoLetra"/>

Output produced by this tag (assuming skin1 set in session):
/xkins/skins/skin1/backgrounds/bg.gif
Arial

Skin name management:

XkinTag
Allows you to set current Skin name in Session.

SaveActualXkinTag
This tag saves current skin name value set in session. This is used along with RestoreActualXkinTag and is useful if you need to change Skin during a JSP.

RestoreActualXkinTag
This restores value saved by SaveActualXkinTag

XkinNameTag
This writes to output the name of the current skin.

Example

Use Skin X set in session

<xkin:saveAcualXkin/>
<xkin:xkin name="skin2"/>
<xkin:xkinName/>

Use Skin2 templates, resources, etc.

<xkin:RestoreAcualXkin/>

Again, use Skin X set in session

Using Xkins in a no-web environment

You don't need a web environment in order to use Xkins. You can use Xkins in a context where no httpession exists.

For instance, if you are in a java class where you need to send an e-mail and you want e-mail text to use a template defined by Xkins, you can code as follows:

Xkins xks = (new XkinsLoader()).loadSkins("/config/xkins/mail-templates.xml");
Skin skin = xks.getSkin(XkinProcessor.DEFAULT_SKIN);
XkinProcessor xkpBody = new XkinProcessor();
Template tmpBody = skin.getTemplate("mail");
xkpBody.setTemplate(tmpBody);
xkpBody.addParameter("text", "This is a text");
this.sendMessage(xkpBody.processContent());

Your mail-templates definition will have a Skin with a mail template that receives a "text" parameter:

<?xml version="1.0" encoding="UTF-8"?>
<xkins>
       <!-- SKIN default -->
       <skin name="default" url="/skins/default">
             <processor type="net.sf.opentranquera.xkins.core.processor.VelocityTemplateProcessor"/>
             <template name="mail">
                    <content><![CDATA[
<table>
<tr bgcolor="cyan">
<td>$text</td>
</tr>
</table>
             ]]></content>
             </template>
       </skin>
</xkins>

Your mail will has the following body:

<table>
	<tr bgcolor="cyan">
		<td>This is a text</td>
	</tr>
</table>	

Template processor architecture

XkinProcessor is the fašade to Xkins framework. XkinsProcessor process templates content using a class that implements TemplateProcessor interface. Xkins framework comes with a built-in template processor that implements this interface, and you can also write your own TemplateProcessor.

Implementing your own TemplateProcessor

You can implement your own template processor. All you need is to implement TemplateProcessor interface and declare it to be used in processor tag in xkin-definition file.
Xkins bundle comes with an implementation of Velocity templates, so you can use Velocity's templates in xkin-definition file and use xkins capabilities for extend skins and organize paths and resources.
You are free to implement all template processors as you want in any output format (not only HTML), for example, PDF processors, XLS or Microsoft DOC processors, or a template for generating images on the fly.

This diagram shows TemplateProcessor hierarchy:

A template processor can also implement a event notification interface (XkinsEventListener) in order to receive Xkins event if needed.

Velocity template processor:

This is the recomended processor for an enterprise scale application. This processor process templates written in VTL language (see Velocity home page for more information).
All you need to know is that templates parameters are passed to this template and Skin's resources are passed as variables too, but with "res_" prefix.
Alse you can use req, res, app and session objects and Xkins variable bodyContent.
For example, you can refer to a Skin resource from a Velocity Template like this: $res_spacer, assuming that resource name is spacer.
This processor implements a TemplateLoader and create and caches Velocity templates in a lazy fashion. Some metrics shows that VelocityTemplateProcessor is 100% faster than Xkins own Template processor. Of course, this performance can still be improved and contributions are welcomed.
It also implements XkinsEventListener to clear template's cache when xkins are reloaded.

Xkins own template processor:

The default processor transforms template content replacing parameters and resources properly in runtime. You can use this processor if tou don't want to use Velocity Template processor for whatever reason you have.
When writing template content, you can include parameters and resources. Parameters and resources are defined in the following way:

Properties:
${pro:propertyName}
where propertyName is the property to be replaced at runtime by its value.

Resources:
${res:resourceName}
where resourceName is the resource to be replaced at runtime. Resouces can be Constants or Elements. A resource has a getData method that is used by the TemplateProcessor to render the value. When a resource is a Constant, constant value is rendered. If Element is the resource, a string generated by "skin url + path url + element url" is rendered.

Built-in commands:
${jsp:parameter}
jsp command allows template creator access to context page in runtime, without the need to explicitly pass this values as parameters. The parameter can be:

  • bodyContent, gets taglib body content.
  • request(attrName), gets attrName attribute from request.
  • session(attrName), gets attrName attribute from session.
  • application(attrName), gets attrName attribute from servlet context

This TemplateProcessor uses a cache schema that stores processed content if template has only static and fixed resources. You can add more commands to this processor by implementing Command interface and declaring it to be used by processor. For example, you could create an i18n command that takes a key and write the ResourceBundle result according to user's locale.

Xkins Forms: Taglibs for making forms.

This example will show you a creation of a form using Xkins Forms.
This tags simplifies Xkins usage for creating forms integrated with Struts 1.1.

Xkins forms taglibs are:

  • frame: This will generate a frame for your form.
  • row: This tag inserts a row in the form. This must be nested in a frame. Rows are added to the frame and frame checks all rows to see if they have the equal in count of fields. If not, do the padding to complete the row.
  • field: This generates a label/input field. This must me nested in a row.
  • buttons: This tag holds all form buttons.
  • button: This is a button for the form.
  • execute: This is a button that executes a dispatch method to a Strut's Action.

Skin Components and Xkins Forms

This example will show how to create Skin Components and we will use Xkins Forms to render a form.
We will create four Skins: Primavera, Verano, Otono and Invierno. Each one can be packed in a single file and can be distributed independently.

Xkins-definition file

You declare here four Skin Components. Each one has an url (directory where elements and templates resides) and a definition.

<?xml version="1.0" encoding="UTF-8"?>
<xkins>
	<skin name="invierno" url="/skins/forms/invierno" definition="/definition.xml"/>
	<skin name="primavera" url="/skins/forms/primavera" definition="/definition.xml"/>
	<skin name="verano" url="/skins/forms/verano" definition="/definition.xml"/>
	<skin name="otono" url="/skins/forms/otono" definition="/definition.xml"/>
</xkins>

Skin Component definition file

We will show here default skin (invierno) for examples purpouses. This file will reside in /skins/forms/invierno directory, as this is skin's url declared in the previous xkins-definition file.
<?xml version="1.0" encoding="UTF-8"?>
<skin name="invierno">
	<processor type="net.sf.opentranquera.xkins.core.processor.VelocityTemplateProcessor"/>
	<constant name="fieldColspan" value="5"/>
	<element name="spacer" path="images" url="/spacer.gif"/>
	<path name="css" url="/css"/>
	<path name="images" url="/images"/>
	<element name="stylesheet" path="css" url="/textos.css"/>
	<template name="frame">
		<!--
		pro:width
		pro:title
		pro:footer
		pro:buttons
		pro:mandatoryCaption
		jsp:bodyContent
		-->
		<content><![CDATA[
<center>
	<LINK href="$res_stylesheet" type="text/css" rel="stylesheet">
     <TABLE cellSpacing=0 cellPadding=0 width="$width" bgColor=#000000 border=0>
          <TBODY>
          <TR>
            <TD>
              <TABLE cellSpacing=1 cellPadding=0 width="100%" border=0>
                <TBODY>
                <TR>
                  <TD bgColor=#448ccb>

                    <TABLE height=20 cellSpacing=0 cellPadding=0 width="100%" border=0>
                      <TBODY>
                      <TR>
                        <TD>
                        	<IMG height=8 src="$res_spacer" width=18>
                        	<FONT face="Verdana, Arial, Helvetica, sans-serif" color=#ffffff size=1>
                        		$title
                        	</FONT>
                        </TD>
                        <TD vAlign=bottom align=left>
                        </TD>
                      </TR>
                     </TBODY>
                    </TABLE>
                   </TD>
                 </TR>
		        <TR><TD height=3 bgcolor="white">$mandatoryCaption</TD></TR>
		        <TR>
		          <TD vAlign=top bgColor=#f5f5f5>
        			<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
		              <TBODY>
			        <TR><TD height=5><IMG height=8 src="$res_spacer" width=18></TD></TR>
        			  <TR>
		                <TD vAlign=top align="center" width="100%" >
        			      <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0  >
								$bodyContent
						  </TABLE>
						</td>
					  </tr>
                    </TBODY>
					</table>
				</td>
			</tr>
    <TR><TD height=30 bgcolor="white" align="right">$buttons</TD></TR>
         </TBODY>
		</table>
		</td>
	</tr>
   </TBODY>
</table>
</center>
	]]></content>
	</template>
	<template name="frameFooter">
		<!--
		pro:footer
		-->
		<content><![CDATA[
<td>$footer</td>
		]]></content>
	</template>
	<template name="frameMandatoryCaption">
		<!--
		pro:texto
		-->
		<content><![CDATA[<div align='right'><span class='asterisco'>
		<strong>* </strong><strong></strong></span><span 
		class='textGray'><strong>$texto</strong></span></div>
	]]></content>
	</template>
	<template name="field">
		<!--
		pro:label
		pro:input
		-->
		<content><![CDATA[
$label
$input
			]]></content>
	</template>
	<template name="fieldLabel">
		<!--
		pro:label
		-->
		<content><![CDATA[
<TD> </TD>
 <TD class=texto1 width=80 height=25>
 $label</TD>
<TD> </TD>
			]]></content>
	</template>
	<template name="fieldInput">
		<!--
		pro:input
		pro:colspan
		-->
		<content><![CDATA[
 <TD colSpan=$colspan class=texto1 >
<b>$input</b>
</td>
<TD> </TD>
			]]></content>
	</template>
	<template name="fieldLabelMandatory">
		<!--
		pro:label
		-->
		<content><![CDATA[
<TD> </TD>
 <TD class=texto1 width=80 height=25>
 $label</TD>
<TD> </TD>
			]]></content>
	</template>
	<template name="fieldInputMandatory">
		<!--
		pro:input
		pro:colspan
		-->
		<content><![CDATA[
 <TD colSpan=$colspan>
$input
</td>
<TD> </TD>
			]]></content>
	</template>
	<template name="row">
		<!--
		jsp:bodyContent
		pro:colspan
		-->
		<content><![CDATA[
<tr>
$bodyContent
</tr>
<tr>
<td colspan="$colspan"> </td>
</tr>
			]]></content>
	</template>
	<template name="fieldPadding">
		<content><![CDATA[
<td colspan="$res_fieldColspan"> </td>
			]]></content>
	</template>
	<template name="nestedField">
		<!--
		jsp:bodyContent
		-->
		<content><![CDATA[
<td colspan="$res_fieldColspan"><table border=0 cellspacing=0 cellpadding=0><tr>
$bodyContent
</tr></table></td>
			]]></content>
	</template>
	<template name="buttons">
		<!--
		jsp:bodyContent
		-->
		<content><![CDATA[
<table cellSpacing=0 cellPadding=0 border=0 ><tr>$bodyContent</tr></table>
			]]></content>
	</template>
	<template name="button">
		<!--
		pro:key
		pro:action
		pro:alt
		-->
		<content><![CDATA[
<td><img src="$res_boton-izq"></td><td background="$res_boton-tile">
<a onclick="return buttonsEnabled;" href="javascript:$action" alt="$alt">
<font face=arial size=1 color=#333333 style="text-transform:uppercase">
  $key  </font></a></td><td><img src="$res_boton-der">
</td><td><img src="$res_spacer" width="10"></td>
		]]></content>
		<element name="boton-der" path="images" url="/boton-der.gif"/>
		<element name="boton-tile" path="images" url="/boton-tile.gif"/>
		<element name="boton-izq" path="images" url="/boton-izq.gif"/>
	</template>
</skin>


Here you have to declare all templates needed by Forms Tags. these templates are:
frame, frameFooter, frameMandatoryCaption, field, fieldLabel, fieldInput, row, fieldPadding, nestedField, buttons and button.
You must also declare a constant named fieldColspan.
If you want to write your own Skin for using with Xkins Forms, you can extend one of these Skins and modify whatever you need.

JSP Code (using Xkins Forms)

This JSP code uses Xkins Forms taglib and renders a form for our example. We will include this JSP 4 times, each one with a diferent Skin, in order to see all together in the same page.

<forms:frame key="Please fill in this information">
	<forms:row>
		<forms:field key="Skin name">
			<xkins:xkinName/>
		</forms:field>
	</forms:row>
	<forms:row>
		<forms:field key="Last Name">
			<input type="text" size="30">
		</forms:field>
		<forms:field key="First Name">
			<input type="text" size="30">
		</forms:field>
	</forms:row>
	<forms:row>
		<forms:field key="Street">
			<input type="text" size="30">
		</forms:field>
		<forms:field>
			<forms:field key="Number">
				<input type="text" size="4">
			</forms:field>
			<forms:field key="Floor">
				<input type="text" size="2">
			</forms:field>
			<forms:field key="Dpt">	
				<input type="text" size="2">
			</forms:field>
		</forms:field>
	</forms:row>
	<forms:row>
		<forms:field key="City">
			<input type="text" size="30">
		</forms:field>
	</forms:row>
	<forms:row align="right">
		<forms:field>
			<forms:field key="ZIP">
				<input type="text" size="8">
			</forms:field>
			<forms:field key="Telephone">
				<input type="text" size="10">
			</forms:field>
		</forms:field>
	</forms:row>
	<forms:buttons>
		<forms:button key="OK" onclick="alert('OK');" 
			confirmMessage="┐Are you sure?" default="true"/>
		<forms:button key="return" gotoLocation="/index.jsp" 
			cancel="true"/>
	</forms:buttons>
</forms:frame>

Screenshots

The following image is an example of four Skins (primavera, verano, otono and invierno) using the same JSP. As you can see, each one looks completly different to the other.

Velocity template processor

This processor is the recomended processor for HTML generation.

This processor is 100% faster than Xkins Template Reference implementation.

Velocity receives properties as Velocity properties, and xkins resources as properties, but with res_ prefix. For example, a xkin resource called "back" is seen by Velocity as $res_back. Also receives objects req, res, app and session just like VelocityServlet does.

VelocityTemplateProcessor implemente TemplateProcessor and uses a XkinsVelocityLoader that extends ResourceLoader.

You can change this implementation or use other ResourceLoader.
you can use xkins to organize your templates and use Xkins capabilities for managing multiples Skins.

For example, you can define a Skin as follows:

	<skin name="skin1" url="/skins/skin1">
		<processor type="net.sf.opentranquera.xkins.core.processor.VelocityTemplateProcessor"/>
		<element name="back" path="backgrounds" url="/back.gif"/>
		<constant name="tipoLetra" value="Tahoma"/>
		<constant name="colorLetra" value="#BBAABB"/>

		<template name="page1">
			<content url="/page1.vm"/>
		</template>
		<template name="page2">
			<content url="/page2.vm"/>
		</template>
		<template name="page3">
			<content url="/page3.vm"/>
		</template>
		<template name="page4">
			<content url="/page4.vm"/>
		</template>
	</skin>
	<skin name="skin2" url="/skins/skin2" extends="skin1">
		<processor type="net.sf.opentranquera.xkins.core.processor.VelocityTemplateProcessor"/>
		<element name="back" path="backgrounds" url="/back2.gif"/>
	</skin>

In this example you declare 4 templates (page1... page4) that are Velocity templates externalized in *.vm files.
This files can use Skin resources (with $res_ patterns) and skin2 extends skin1 and overwrites back element.

What can be done is to extend VelocityServlet to use XkinProcessor for dispatch this VelocityTemplates and use Xkins capabilities.

Integrating with Struts

Struts 1.1 plugin

Xkins comes with a Struts 1.1 plugin to load Xkins:

       <plug-in className="net.sf.opentranquera.xkins.struts.XkinsPlugin">
             <set-property property="config" value="/xkin-panel-definition.xml"/>
             <set-property property="defaultSkinName" value="default"/>
       </plug-in>

Xkins Forms and Struts

Xkins forms is intended to be used with Struts. Xkins Forms tags uses Struts mapping and allows to execute DispatchAction methods.

Struts Layout

This framework has a skin solution and can be extended.
Each tag in this framework has a renderer and you declare it in a property file.
You can use xkins to implement this interfaces and use Skin features.

For example, if you use Xkins implementation of this interfaces in the following JSP:


<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-layout.tld" prefix="layout" %>
<HTML>
<html:errors property="org.apache.struts.action.GLOBAL_ERROR"/>
<layout:form action="/logon.do" focus="username" styleClass="FORM" width="50%" key="logon.title">
  <layout:text key="prompt.username" property="username" size="16" maxlength="16" isRequired="true" />
  <layout:password key="prompt.password" property="password" size="16" maxlength="16" isRequired="true" />
  <layout:formActions>
      <layout:submit property="submit" value="Submit"/>   
      <layout:reset/>      
  </layout:formActions>
</layout:form>    
</HTML>

HTML generated by this JSP would be like this:
Using Skin default (same as BasicPanel):

Using skin 1

And Using Skin 2

Jave Server Faces

Xkins can be used to implement a RenderKit in JavaServerFaces. An implementation exists and is called XkinsFaces.

XkinsFaces is set of renderers that acts as decorators of existing renderers and implements Renderers. XkinsFaces works on top of Xkins and has a basic Skin that contains all Xkins Templates needed by the renderers.

A valid xkinsFaces Skin must extend this basic Skin in order to work. So, basic skin defines a "well known" set of templates to implement and use with XkinsFaces. Anyone can create his or her own Skin extending basic, deploy this new skin in a XkinsFaces application and the webapp will look like this skin commands. In a future, there could be lots of skins you could download and deploy in your webapp to look diferent without changing anything of your JSPs, classes or HTML.

Decorators configurtation

Xkins works like a decorator for existing renderers. Decorated renderers are defined as constants in definition.xml of faces-basic skin:
	<constant name="FormDecorated" value="org.apache.struts.faces.renderer.FormRenderer"/>

In this cases, Decorated Renderer is Strut's Faces FormRenderer. If you have other JSF implementation, you should change this value.

    <component>
        <type>javax.faces.component.UICommand</type>
        <renderer>
            <type>ButtonRenderer</type>
            <class>net.sf.opentranquera.faces.renderkit.XkinsCommandRenderer</class>
        </renderer>
    </component>

Renderers are declared in xkins-faces-config.xml

<faces-config>
  <!-- Xkins renderkit -->
  <render-kit>
    <renderer>
      <renderer-type>Button</renderer-type>
      <renderer-class>net.sf.opentranquera.xkins.faces.renderkit.XkinsButtonRenderer</renderer-class>
    </renderer>
    <renderer>
      <renderer-type>StrutsForm</renderer-type>
      <renderer-class>net.sf.opentranquera.xkins.faces.renderkit.XkinsFormRenderer</renderer-class>
    </renderer>
    <renderer>
      <renderer-type>Grid</renderer-type>
      <renderer-class>net.sf.opentranquera.xkins.faces.renderkit.XkinsGridRenderer</renderer-class>
    </renderer>
    <renderer>
      <renderer-type>Group</renderer-type>
      <renderer-class>net.sf.opentranquera.xkins.faces.renderkit.XkinsGroupRenderer</renderer-class>
    </renderer>
  </render-kit>
</faces-config>

Downloads

You can download Xkins from SourceForge.net.

Xkins is an Open Source project under GNU Lesser General Public License.

Contact information

Xkins is a framework developed by Guillermo Meyer



Home | Download | Powered by SourceForge.net