-

开始本章的内容学习之前,让我们看看http://struts.apache.org给出的几个定义:

术语描述
tag(标签)从JSP,FreeMarker或Velocity内部执行的一小段代码。
template(模板)一些代码,通常是写在FreeMarker上的,可以由某些标签(HTML标签)呈现。
theme(主题)封装在一起以提供公共功能的模板集合。

我们建议再回顾一下Struts2本地化/国际化(i18n)章节,因为我们将再次使用同样的例子来进行练习。

当你在Web页面中使用Struts2 标签(如<s:submit...>,<s:textfield...>等)时,Struts2 框架会生成具有预配置样式和布局的HTML代码。Struts2 具有三个内置主题:

Theme(主题)描述
simple theme没有“bells and whistles”的最小主题。例如,textfield标签呈现HTML<input/>标签无标记、验证、错误报告或任何其他格式或功能。
xhtml theme这是Struts 2使用的默认主题,提供了simple theme具备的所有基础,并添加了几个功能,如HTML的标准两列表布局、每个HTML的标记、验证和错误报告等。
css_xhtml theme这个主题提供了simple theme具备的所有基础,并添加了几个功能,如基于CSS的标准两列布局,对HTML Struts标签使用<div>,HTML Struts每个标签的标记,根据CSS样式表放置等。

如上所述,如果你不指定一个主题,那么Struts2 将默认使用xhtml theme。例如这个Struts2选择标签:

<s:textfield name="name" label="Name" />

生成以下HTML标记:

<tr>
<td class="tdLabel">
   <label for="empinfo_name" class="label">Name:</label>
</td><td>
   <input type="text" name="name" value="" id="empinfo_name"/>
</td>
</tr>

这里empinfo是在struts.xml文件中定义的action名称。

选择主题

你可以在每个Struts2 标签的基础上指定主题,也可以使用以下方法之一指定Struts2 应使用的主题:

  • 特定标签上的theme属性

  • 标签的周边表单标签的theme属性

  • 名为“theme”的页面作用域属性

  • 名为“theme”的请求作用域属性

  • 名为“theme”的会话作用域属性

  • 名为“theme”的应用程序作用域属性

  • struts.properties中的struts.ui.theme属性(默认为xhtml)

以下是在标签级别指定它们的语法,如果你愿意为不同的标签使用不同的主题:

<s:textfield name="name" label="Name" theme="xhtml"/>

因为在每个标签的基础上使用主题并不是很实用,所以只需使用以下标签就可以在struts.properties文件中指定规则:

# Standard UI theme
struts.ui.theme=xhtml
# Directory where theme template resides
struts.ui.templateDir=template
# Sets the default template type. Either ftl, vm, or jsp
struts.ui.templateSuffix=ftl

下面是我们从本地化章节中选择的结果,我们在struts-default.properties文件中使用了默认主题,设置为struts.ui.theme=xhtml,该文件默认情况下位于struts2-core.xy.z.jar文件中。

输出

主题是如何工作的?

对于给定的主题,每个struts标签都有一个关联的模板,如s:textfield -> text.ftls:password -> password.ftl等。这些模板文件压缩在struts2-core.xy.z.jar文件中,它们为每个标签保留预定义的HTML布局。因此Struts2 框架使用Sturts标签和相关模板生成最终的HTML标记代码。

Struts 2 tags + Associated template file = Final HTML markup code.

默认模板已经写在FreeMarker中,它们有扩展名.ftl。你可以使用velocity或JSP设计你的模板,使用struts.ui.templateSuffixstruts.ui.templateDir在struts.properties中设置配置。

创建新主题

创建新主题的最简单方法是复制任何现有的theme/template文件,并进行必要的修改。那么,让我们在WebContent/WEB-INF/classes中创建一个名为template的文件夹,以及一个以新主题名称命名的子文件夹,例如WebContent/WEB-INF/classes/template/mytheme。从这里,你可以从头开始构建模板,或者你可以从Struts2 现有版本中复制模板,并根据需要修改它们。
出于学习的目的,我们将修改现有的默认模板xhtml。那么现在先将内容从struts2-core-x.y.z.jar/template/xhtml复制到我们的主题目录,并只修改WebContent/WEB-INF/classes/template/mytheme/control.ftl文件。当我们打开control.ftl时它会显示以下几行:

<table class="${parameters.cssClass?default('wwFormTable')?html}"<#rt/>
<#if parameters.cssStyle??> style="${parameters.cssStyle?html}"<#rt/>
</#if>
>

让我们将以下内容修改到上面的control.ftl文件中:

<table style="border:1px solid black;">

如果你查看form.ftl,你会发现它正在使用这个control.ftl文件,但form.ftl是从xhtml主题中引用这个文件。那么让我们把它做如下修改:

<#include "/${parameters.templateDir}/xhtml/form-validate.ftl" />
<#include "/${parameters.templateDir}/simple/form-common.ftl" />
<#if (parameters.validate?default(false))>
  onreset="${parameters.onreset?default('clearErrorMessages(this);
  clearErrorLabels(this);')}"
<#else>
  <#if parameters.onreset??>
  onreset="${parameters.onreset?html}"
  </#if>
</#if>
>
<#include "/${parameters.templateDir}/mytheme/control.ftl" />

我们假设你不太了解FreeMarker模板语言,不过你仍可以通过查看.ftl文件得到一个很好的想法。 不管怎样,让我们先保存以上更改,并返回到我们的本地化示例,创建具有以下内容的WebContent/WEB-INF/classes/struts.properties文件:

# Customized them
struts.ui.theme=mytheme
# Directory where theme template resides
struts.ui.templateDir=template
# Sets the template type to ftl.
struts.ui.templateSuffix=ftl

现在在此更改后,右键单击项目名称,然后单击“Export”>“ WAR File”以创建WAR文件。然后在Tomcat的webapps目录中部署WAR文件。最后,启动Tomcat服务器并尝试访问URL http://localhost:8080/HelloWorldStruts2。将显示以下界面:

主题和模板

你可以看到窗体组件周围的边框,这是我们从xhtml主题复制之后在out主题中所做更改的结果。如果你稍微学习一下FreeMarker,那么就能够非常容易地创建或修改你的主题。至少现在,你一定对Sturts2 主题和模板有了基本的了解,是吗?