Here is a possible way to customise the JSP taglib provided by the Struts2 framework.
The topics covered in this post are:
- add a custom attribute to a given tag (e.g. TextField)
- customise the Freemarker template to modify the generated HTML code
- define new themes and templates
- generate the new TLD for the customised version of the taglib
- deploy it in a web application (WAR file)
The sample I have created implements a read-only version of the Struts2 JSP taglib: if a given attribute (i.e. viewMode) is set to true then a simple label (plain text) is rendered, instead of the html code for the input type, making the information on the form not editable.
This, in principle, achieves the same purpose as the disabled attribute but it looks much nicer on the web form.
Introduction
Few words about the elements of the Struts2 UI component framework should help to understand better the scenario.
JSP Tag: implementation of the JSP tag (e.g TextFieldTag). Notice Struts2 has also Velocity and FreeMarker tags
UI Component: actual implementation of the behavior of the component (e.g TextField)
Template: FreeMarker template which renders the html markup (e.g. <input type=”text”….)
Theme: collection of templates (e.g. simple or ajax)
Create custom TextFieldTag
Extend the org.apache.struts2.views.jsp.ui.TextFieldTag and add your new code.
public class TextFieldTag extends
org.apache.struts2.views.jsp.ui.TextFieldTag {
private static final long serialVersionUID = 5811285953670562288L;
protected String viewmode;
public Component getBean(ValueStack stack, HttpServletRequest req,
HttpServletResponse res) {
return new TextField(stack, req, res);
}
protected void populateParams() {
super.populateParams();
TextField textField = ((TextField) component);
textField.setViewmode(viewmode);
}
public void setViewmode(String viewmode) {
this.viewmode = viewmode;
}
}
This is the actual implementation of the new JSP tag (which I called with the same name – TextFieldTag – but you don’t have to).
Create custom TextField
Extend the org.apache.struts2.components.TextField and add your new code.
@StrutsTag(name = "textfield",
tldTagClass = "com.mycompany.struts2.views.jsp.ui.TextFieldTag",
description = "Render an HTML input field of type text",
allowDynamicAttributes = true)
public class TextField extends org.apache.struts2.components.TextField {
protected String viewmode;
public TextField(ValueStack stack, HttpServletRequest request,
HttpServletResponse response) {
super(stack, request, response);
}
protected void evaluateExtraParams() {
super.evaluateExtraParams();
if (viewmode != null) {
addParameter("viewmode", findValue(viewmode, Boolean.class));
}
}
@StrutsTagAttribute(description = "Viewmode", type = "Boolean",
defaultValue = "false")
public void setViewmode(String viewmode) {
this.viewmode = viewmode;
}
}
Now this is interesting: Struts2 taglib architecture involves the UI components as the base for managing the actual behaviour of the tags. The new component (which again I called with the same name) includes the Struts2 annotations required to document the tags:
@StrutsTag: annotation for marking a Struts tag
@StrutsTagAttribute: annotation for marking an attribute of a Struts tag
Define your own templates (theme)
The actual HTML generated by the JSP tag is stored externally to the tag, in facts it uses FreeMarker, a powerful Java Template Engine.
Browse through the Struts2 core source (/core/src/main/resources/template) to see the provided FreeMarker templates. In my sample I have created a new theme which extends the Struts2 simple theme:
- create a folder /resources/template/myTheme
- copy the templates you want to modify (e.g text.ftl, select.ftl, etc..)
- create a theme.properties which states parent=simple (theme inheritance)
Let’s say we want to modify text.ftl to display a simple text when the viewmode attribute is set to true.
<#if parameters.viewmode?default(false)>
<#-- viewmode is true: print simple text -->
<@s.property value="parameters.nameValue"/><#t/>
<#else>
<#-- viewmode is false (or not provided): invoke parent -->
<#include "/${parameters.templateDir}/simple/text.ftl" />
</#if>
Generate the TLD file
The TLD is generated with the Tobago plugin.
Deploy taglib in your Web application
Just drop the new taglib jar file in the application WEB-INF/lib (or better define the Maven dependency!).
Additionally in the Web application struts.properties define
struts.ui.theme = myTheme
This allows to set myTheme as the default theme used by the application.
Code the JSP
Finally to use the customised Struts2 tags in your JSP:
<%@ taglib prefix="ss" uri="/extended-struts2-tags" %>
....
....
<ss:textfield name="name" viewmode="true" size="35" />
<ss:select name="type"
viewmode="true"
list="allTypes"
listKey="id"
listValue="name"/>
Normally the value of the “viewmode” attribute can be set in the Action class, using a boolean (for instance the return of a method which verifies the user privileges).
Download the sample taglib
Download the sample tag lib.
It is a Maven2 project which includes the Java code, the modified Freemarker templates and the POM.xml.

June 5, 2009 at 8:45 am |
There is no textfield.ftl: the template for the textFieldTag is called text.ftl
Apologies if the image (boxes2.jpg) is confusing: it should read “Text Template” instead “TextField” Template
June 3, 2009 at 5:59 pm |
I can’t find the textfield.ftl to overwrite. Where is it?
March 18, 2009 at 7:48 pm |
Hello
it’s in the pom.xml (sample taglib)
org.apache.struts
struts2-core
2.1.6
B
March 18, 2009 at 7:33 pm |
Hello, what version of struts 2 you are using?