Edit on GitHub
<< back to Themes and Templates
xhtml theme
The xhtml provides all the basics that the simple theme provides and adds several features.
Wrapping the Simple Theme
The xhtml theme uses the “wrapping” technique described by Extending Themes . Let’s look at how
the HTML tags are wrapped by a standard header and footer. For example, in the text.ftl
template, the controlheader.ftl
and controlfooter.ftl
templates are wrapped around the simple template.
<#--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<#include "/${attributes.templateDir}/${attributes.expandTheme}/controlheader.ftl" />
<#include "/${attributes.templateDir}/simple/text.ftl" />
<#include "/${attributes.templateDir}/${attributes.expandTheme}/controlfooter.ftl" />
The controlheader.ftl
is referenced using ${parameters.theme}
so that the code can be reused
by the ajax theme .
Now let’s look at the controlheader.ftl
and controlheader-core.ftl
. Again, these are split up for easy re-use with
the ajax theme ) contents:
<#--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<#include "/${attributes.templateDir}/${attributes.expandTheme}/controlheader-core.ftl" />
<td
<#if attributes.align?? >
class="align-${attributes.align}"
<#else >
class="tdInput"
</#if>
><#t/>
<#--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<#--
Only show message if errors are available.
This will be done if ActionSupport is used.
-->
<#assign hasFieldErrors = attributes.name?? && fieldErrors?? && fieldErrors.get(attributes.name)??/>
<#if (attributes.errorposition!"top") == 'top'>
<#if hasFieldErrors>
<#list fieldErrors.get(attributes.name) as error>
<tr errorFor="${attributes.id}">
<td class="tdErrorMessage" colspan="2"><#rt/>
<span class="errorMessage">${error}</span><#t/>
</td><#lt/>
</tr>
</#list>
</#if>
</#if>
<#if !attributes.labelPosition?? && (attributes.form.labelPosition)??>
<#assign labelPos = attributes.form.labelPosition/>
<#elseif attributes.labelPosition??>
<#assign labelPos = attributes.labelPosition/>
</#if>
<#--
if the label position is top,
then give the label it's own row in the table
-->
<tr>
<#if (labelPos!"") == 'top'>
<td class="tdLabelTop" colspan="2"><#rt/>
<#else>
<td class="tdLabel"><#rt/>
</#if>
<#if attributes.label??>
<label <#t/>
<#if attributes.id??>
for="${attributes.id}" <#t/>
</#if>
<#if hasFieldErrors>
class="errorLabel"<#t/>
<#else>
class="label"<#t/>
</#if>
><#t/>
<#if (attributes.required!false) && ((attributes.requiredPosition!"right") != 'right')>
<span class="required">*</span><#t/>
</#if>
${attributes.label}<#t/>
<#if (attributes.required!false) && ((attributes.requiredPosition!"right") == 'right')>
<span class="required">*</span><#t/>
</#if>
${attributes.labelseparator!":"}<#t/>
<#include "/${attributes.templateDir}/${attributes.expandTheme}/tooltip.ftl" />
</label><#t/>
</#if>
</td><#lt/>
<#-- add the extra row -->
<#if (labelPos!"") == 'top'>
</tr>
<tr>
</#if>
The header used by the HTML tags in the xhtml theme is complicated. However, a close look reveals that the logic produces
two behaviors: either a two-column format or a two-row format. Generally the two-column approach is what we want, so that
is the default option. To use the two-row approach, change the labelposition
parameter to top
.
The fieldErrors
, usually caused by Validation , are printed out as a row above
the HTML form element. Some people prefer that the errors display elsewhere, such as in a third column. If you wish
to place these elsehwere, overriding the headers is easy, allowing you to continue to use the other features provided
by this theme. See Template Loading for more information on how to do this.
The primary objective of controlfooter.ftl
is to close the table. But, before the table closes, the template checks
for an after
parameter.
<#--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
${attributes.after!}<#t/>
</td><#lt/>
</tr>
<#if (attributes.errorposition!"top") == 'bottom'>
<#assign hasFieldErrors = attributes.name?? && fieldErrors?? && fieldErrors.get(attributes.name)??/>
<#if hasFieldErrors>
<#list fieldErrors.get(attributes.name) as error>
<tr errorFor="${attributes.id}">
<td class="tdErrorMessage" colspan="2"><#rt/>
<span class="errorMessage">${error}</span><#t/>
</td><#lt/>
</tr>
</#list>
</#if>
</#if>
While after
isn’t an attribute supported by any of the Struts Tags , if you are using
FreeMarker Tags , Velocity Tags , or the param tag in any
template language, you can add an after
parameter to place any content you like after the simple theme
template renders. The after
attribute makes it easier to fine-tune HTML forms for your specific environment.
Special Interest
Two xhtml templates of special interest are head
and form
.
xhtml head template
The xhtml head template extends the simple head template and provides an additional CSS that helps
render the form elements.
<#--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<@s.link rel="stylesheet" href="${base}${attributes.staticContentPath}/xhtml/styles.css" type="text/css" />
<#include "/${attributes.templateDir}/simple/head.ftl" />
The head template imports a style sheet. The contents of styles.css are:
/*
* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
.wwFormTable {}
.label { font-style : italic ; }
.errorLabel { font-style : italic ; color : red ; }
.errorMessage { font-weight : bold ; color : red ; }
.checkboxLabel {}
.checkboxErrorLabel { color : red ; }
.required { color : red ;}
.tdLabel { text-align : right ; vertical-align : top ; }
.tdTransferSelect { text-align : center ; vertical-align : middle ;}
.tdLabelTop { text-align : left ; vertical-align : top ;}
.tdCheckboxLabel { text-align : right ; vertical-align : top ;}
.tdCheckboxInput { text-align : left ; vertical-align : top ;}
.tdCheckboxErrorMessage { text-align : left ; vertical-align : top ;}
.tdErrorMessage { text-align : center ; vertical-align : top ;}
.formButton { text-align : right ;}
.tdInput { text-align : left ;}
.align-center { text-align : center ;}
.align-right { text-align : right ;}
.align-left { text-align : left ;}
.align-justify { text-align : justify ;}
The xhtml form template sets up the wrapping table around all the other form elements. In addition to creating this
wrapping table, the opening and closing templates also, if the validate
parameter is set to true, enable
Pure JavaScript Client Side Validation .
<#--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<#include "/${attributes.templateDir}/${attributes.expandTheme}/form-validate.ftl" />
<#include "/${attributes.templateDir}/${attributes.expandTheme}/form-common.ftl" />
<#if (attributes.validate!false)>
onreset="<#outputformat 'JavaScript'>${attributes.onreset!'clearErrorMessages(this);clearErrorLabels(this);'}</#outputformat>"
<#else>
<#if attributes.onreset??>
onreset="<#outputformat 'JavaScript'>${attributes.onreset}</#outputformat>"
</#if>
</#if>
>
<#include "/${attributes.templateDir}/${attributes.expandTheme}/control.ftl" />
The closing template, form-close.ftl
:
<#--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<#include "/${attributes.templateDir}/${attributes.expandTheme}/control-close.ftl" />
<#include "/${attributes.templateDir}/simple/form-close.ftl" />
<#include "/${attributes.templateDir}/${attributes.expandTheme}/form-close-validate.ftl" />
<#if attributes.focusElement??>
<@s.script>
StrutsUtils.addOnLoad(function() {
var element = document.getElementById("${attributes.focusElement?js_string}");
if(element) {
element.focus();
}
});
</@s.script>
</#if>
The xhtml form template sets up the wrapping table around all the other xhtml theme form elements.
In addition to creating this wrapping table, the opening and closing templates also, if the validate
parameter is set
to true
, enable Pure JavaScript Client Side Validation .
See the form.ftl contents:
<#--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<#include "/${attributes.templateDir}/${attributes.expandTheme}/form-validate.ftl" />
<#include "/${attributes.templateDir}/${attributes.expandTheme}/form-common.ftl" />
<#if (attributes.validate!false)>
onreset="<#outputformat 'JavaScript'>${attributes.onreset!'clearErrorMessages(this);clearErrorLabels(this);'}</#outputformat>"
<#else>
<#if attributes.onreset??>
onreset="<#outputformat 'JavaScript'>${attributes.onreset}</#outputformat>"
</#if>
</#if>
>
<#include "/${attributes.templateDir}/${attributes.expandTheme}/control.ftl" />
The closing template, form-close.ftl :
<#--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<#include "/${attributes.templateDir}/${attributes.expandTheme}/control-close.ftl" />
<#include "/${attributes.templateDir}/simple/form-close.ftl" />
<#include "/${attributes.templateDir}/${attributes.expandTheme}/form-close-validate.ftl" />
<#if attributes.focusElement??>
<@s.script>
StrutsUtils.addOnLoad(function() {
var element = document.getElementById("${attributes.focusElement?js_string}");
if(element) {
element.focus();
}
});
</@s.script>
</#if>