6.5 模板和主题的原理与方法
前文已经介绍过关于模板和主题的概念,本节中将讨论模板和主题的原理与方法,以及如何开发自己的模板和主题。
6.5.1 模板装载
Struts2的模板默认情况下总是FreeMarker模板(在以前的WebWork中是Velocity)。标签模板装载方式:首先搜索Web应用程序,然后搜索classpath。这和其他FreeMarker文件的加载方式一样,例如在result中可以配置使用FreeMarker作为结果页面。
模板是基于主题和模板目录来装载的。模板目录使用struts.ui.templateDir属性,在struts.properties里来定义(默认是_template_)。这意味着,如果一个标签使用了ajax主题,下面的两个位置将会被搜索(按照顺序):
1)在Web应用中:/template/ajax/template.ftl。
2)在classpath里:/template/ajax/template.ftl。
Struts2自带的模板都包含在Struts2的jar (classpath) 中,可能会发现有些情况需要覆盖(override)特定的模板来为应用提供独特的功能。例如,可能希望改变select标签的输出,与其创建一个全新的模板并改变每个使用那个模板的标签,可以覆盖内置的select.ftl模板,只要从jar文件里面复制这个文件到一个新的/template/xhtml/select.ftl目录中,在此基础上修改就可以了。
Struts2提供3种模板引擎,可以通过struts.properties中的struts.ui.templateSuffix属性控制:
❑ftl(默认):基于FreeMarker的模板引擎。
❑vm:基于Velocity的模板引擎。
❑jsp:基于JSP的模板引擎。
如果选择了使用vm或者JSP ,必须自己完全实现模板和主题,这是很大量的工作,参考图6.8。
6.5.2 选择主题
主题可以使用不同的规则来选择,按照下面的顺序:
1)特定标签上的主题属性。例如:
<s:textfield label="%{getText("state.label")}" name="state" theme="sample"/>
2)一个标签外围的form标签的主题属性。
可以简单地改变form的theme属性来覆盖整个表单的主题设置。这可以轻松地在几个选择的地方使用ajax主题。
3)page会话范围内的以theme为名称的属性。
4)request会话范围内的命名为theme的属性。可以基于用户的request来改变主题。如果根据请求的不同而改变结果页面的风格,这可能很有用。
5)session会话范围内的命名为theme的属性。可以基于用户的session来改变theme。如果需要用户能个性化他们的界面感观时,每个用户可以自定义自己的风格,这可能很有用。
6)application会话范围内的命名为theme的属性。
7)struts.properties内的struts.ui.theme属性(默认是xhtml)。
如果想要改变整个应用的主题,调整struts.properties。主题的选择可参考图6.14所示。
图6.14 主题和模板加载图
6.5.3 Struts2自带主题
Struts2自带了4种主题,可以根据需要来选择不同的主题,甚至同一个网页中使用多个主题。
1. simple主题
simple主题提供了“不加渲染”的HTML元素支持,被认为是底层的结构,可以用来构建附加的功能或者行为。例如,textfield标签输出HTML<input/>标签,不带额外的label,校验错误报告或者其他东西。如果需要额外的行为,请浏览xhtml主题。
说明
xhtml主题和css_xhtml主题都是直接包装了simple主题。可以模仿它们,利用包装来开发自己的主题。
2. xhtml主题
xhtml主题是Struts2的默认主题。它提供了所有simple主题提供的基本要素,xhtml主题使用了包装技术,还加上一些附加的特性:
❑ 标准的两列表格布局,针对HTML Tags(form、textfield、select等)。
❑ 每个HTML Tags的label,可以在左边或者上边,依赖labelposition属性的设置。
❑ 校验错误报告。
❑ 纯JavaScript客户端校验在浏览器上使用100%的JavaScript。
3. css_xhtml主题
css_xhtml主题除了提供所有simple主题提供的所有基本元素外,还提供了这些额外的特性:
❑ 标准的两列基于CSS的布局,使用<div>方式来设置HTML标签(form、textfield、select等)。
❑ 为每个HTML标签设置label,根据CSS的设置决定位置。
❑ 校验错误报告。
❑ 纯JavaScript客户端校验在浏览器上使用100%的JavaScript。
4. AJAX主题
AJAX主题扩展了xhtml主题,在它的父主题提供的每件事情之上提供了AJAX特性。这个主题使用了两个流行的AJAX/JavaScript库:Dojo和DWR。
图6.15 Struts2结构图
Dojo是一个非常强大的、面向对象的、开源的JavaScript工具箱。它为开发Web胖客户端程序提供了一套完整的Widget和一些特效操作。
DWR全称Direct Web Remoting,是一个Web远程调用框架。利用这个框架可以让AJAX开发变得很简单。利用DWR可以在客户端利用JavaScript直接调用服务端的Java方法并返回值给JavaScript,就好像直接由本地客户端调用一样。
AJAX主题带来的AJAX特性包括:
❑ AJAX客户端校验。
❑ Remote form提交支持(最好和submit标签一起工作)。
❑ 一个高级的div模板提供了动态装载部分HTML的功能。
❑ 一个高级的a模板提供了加载并执行远端的JavaScript的能力。
❑ 一个仅支持AJAX的tabbedPanel实现。
❑ 一个“富”的pub-sub事件模型。
这4种主题的关系如图6.15所示。
注意
由于Struts2的AJAX标签使用了Dojo工具箱,这样对浏览器的要求比较高,需要IE 5.5和Firefox 1.0以上版本才能正常使用。
6.5.4 自定义主题
有时可能想要在一个已存在的主题里简单地覆盖一个模板,如前面讲述的模板装载介绍的或者创建一个可选的模板。然而其他时候可能想要创建自己的整个主题,特别是计划为组织构建一个丰富的、唯一的并且可复用的一套模板时。
有3种方法来创建一个新的主题:
❑ 白手起家,从头创建一个新的主题(困难)。
❑ 扩展一个已存在的主题。
❑ 包装一个已存在的主题。
注意
不推荐从头创建一个新的主题。更恰当地说simple主题提供了扩展或者包装需要的足够的基本要素,从而来创建自己唯一的主题。经常情况下两种方法都用了一些,因为它们不是互斥的。
(1)包装一个存在的主题
xhtml主题中广泛引用了wrapping (包装)技术。例如,一个模板可能是这样的:
<#include "/${parameters.templateDir}/xhtml/controlheader.ftl" /> <#include "/${parameters.templateDir}/simple/xxx.ftl" /> <#include "/${parameters.templateDir}/xhtml/controlfooter.ftl" />
这个模板简单地使用一个header和一个footer包装了simple主题的已存在的模板。这是一种强大的方法,在simple主题提供的基本的HTML元素外围增加额外的行为。
(2)扩展一个存在的主题
Struts2提供的主题基础设施也允许主题来扩展一个存在的主题。这意味着一个主题可以包含一个theme.properties,其中有一个parent设置,包含了想要扩展的主题的名字。例如,AJAX主题就是用这种方式扩展xhtml主题的。
扩展一个主题,不需要实现Ta g s里用到的每个模板。也就是说,只需要实现希望覆盖的模板,其他的模板将从parent模板中装载。