`

深入 Facelets (三)Facelets 模板技术

阅读更多

For any view technology to succeed, it must have some aspect of templating and re-use that's both easy to use and understand. Facelets technology solves this issue in a way that is ideal for JavaServer Faces while keeping that sense of familiarity to traditional, tag-based user interfaces. This article covers the possible ways to increase re-use and simplify maintenance on your JavaServer Faces project.

When people first start creating web pages, they often find themselves repeating content across multiple files. As a developer, this can be frustrating when your object-oriented tendencies kick in. Wouldn't it be nice to simply maintain that content in one spot?

Getting Started?

The first approach to templating and re-use is creating a template. A web page is often composed of some basic parts: header, body, and footer. With Facelets, you can pull those common elements into a single page, creating a template with editable areas, as shown in the following sample template:

  1. <!-- template.xhtml -->  
  2.    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"    
  3.    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  4.    <html xmlns="http://www.w3.org/1999/xhtml"    
  5.    xmlns:ui="http://java.sun.com/jsf/facelets">  
  6. <head>  
  7.    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />  
  8.    <title>Sample Template</title>  
  9. </head>  
  10. <body>  
  11.    <h1>#{title}</h1>  
  12.    <div><ui:insert name="menu"/></div>  
  13.    <p><ui:insert name="body"/></p>  
  14.   
  15. </body>  
  16. </html>  

The ui:insert tag for menu and body mark areas that change on a per-page basis. You can create other pages that will use this template and provide content for both your menu and body.

xml 代码
  1. <!-- template-client.xhtml -->  
  2.    <!-- content above will be trimmed -->  
  3.    <ui:composition template="template.xhtml">  
  4.      <ui:param name="title" value="Here's my Title"/>  
  5.      <ui:define name="menu">Here's My Menu</ui:define>  
  6.      <ui:define name="body">Here's My Body</ui:define>  
  7.      </ui:composition>  
  8.    <!-- content below will be trimmed -->  

This example page introduces another tag: <ui:composition/>. This tag provides a couple features. It trims any content around it. This means you can have a normal HTML page and Facelets will only use or render the content within the ui:composition tag. With this tag, you also have the option of providing a template attribute, which will define how and where its content is layed out.

To pair content within this page and the template, the ui:define tags are used with names that match the ui:insert tags from the template above. For simply passing variables or text, you can use the ui:param tag, which exposes the value as a variable within the template.

When Facelets render the page above with the specified template, you will get the following output:

  1. <!-- template.xhtml -->  
  2.    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"    
  3.    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  4.    <html xmlns="http://www.w3.org/1999/xhtml"    
  5.    xmlns:ui="http://java.sun.com/jsf/facelets">  
  6. <head>  
  7.   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />  
  8.   <title>Sample Template</title>  
  9. </head>  
  10. <body>  
  11.    <h1>Here's my Title</h1>  
  12.    <div>Here's My Menu</div>  
  13.    <p>Here's My Body</p>  
  14.   
  15. </body>  
  16. </html>  
The previous example can be simplified even more if there's only one area that can be changed 
within a template:
  1. <!-- simple-template.xhtml -->  
  2.    ...   
  3. <body>  
  4.    <h1>Title</h1>  
  5.    <!-- editable body -->  
  6.    <p><ui:insert/></p>  
  7. </body>  
  8.    ...   

The page that wants to use the above template can now be as simple as this:

  1. <!-- simple-template-client.xhtml -->  
  2.    <ui:composition template="simple-template.xhtml">  
  3.    Here's My Simple Body   
  4.    </ui:composition>  

Using Includes

The idea of compositions in pages is pretty powerful for defining re-usable content in your web pages. The examples so far have shown how to use compositions with a template for rendering. But what if you want to include that composition in another page? Maybe there's a series of form controls or a complex menu that you would rather separate out into a different document that can be reused or managed separately without cluttering up your page layout.

Facelets provides two ways of including compositions or other pages in general. The first option is with the ui:include tag. This tag should be pretty familiar to web developers:

  1. <!-- include.xhtml -->  
  2.    ...   
  3.    <span id="leftNav">  
  4.    <ui:include src="/WEB-INF/siteNav.xhtml"/>  
  5.    </span>  
  6.    ...   
  7. <!-- siteNav.xhtml -->  
  8.    ..   
  9.    <ui:composition>  
  10.    <!-- myfaces tomahawk components -->  
  11.    <t:tree2 value="#{backingBean.options}" var="opt">  
  12.    ...   
  13.    </t:tree2>  
  14.    </ui:composition>  
  15.    ...   

When Facelets processes the include.xhtml, siteNav.xhtml will have all of its content within the ui:composition included into include.xhtml:

  1. <!-- include.xhtml -->  
  2.    ...   
  3.  <span id="leftNav">  
  4.    <!-- myfaces tomahawk components -->  
  5.    <t:tree2 value="#{backingBean.options}" var="opt">  
  6.    ...   
  7.    </t:tree2>  
  8.  </span>  
  9.  ...  

If you would like to pass variables to siteNav.xhtml, to be used with the tree component, then you can use the ui:param tag:

  1. <!-- include.xhtml -->  
  2.    ...   
  3.  <span id="leftNav">  
  4.    <ui:include src="/WEB-INF/siteNav.xhtml">  
  5.    <ui:param name="menuBean" value="#{backingBean.options}"/>  
  6.    </ui:include>  
  7.  </span>  
  8.  ...  
  1. <!-- siteNav.xhtml -->  
  2.    ...   
  3.    <ui:composition>  
  4.    <!-- myfaces tomahawk components -->  
  5.    <t:tree2 value="#{menuBean}" var="opt">  
  6.    ...   
  7.    </t:tree2>  
  8.    </ui:composition>  
  9.    ...  

You can see that now the siteNav.xhtml can just reference the variable menuBean and assume that it will be passed within the ui:include tag. This allows for some flexibility with re-using common components and content.

Facelets provides an even cleaner solution to ui:include and  ui:param by supporting custom tags. Don't worry, you don't have to write any Java code. To make siteNav.xhtml a reusable tag, you must create a simple XML taglib file:

  1. <facelet-taglib>  
  2.    <namespace>">http://www.mycompany.com/jsf</namespace>  
  3.    <tag>  
  4.    <tag-name>siteNav.xhtml</tag-name>  
  5.    <source>/WEB-INF/tags/siteNav.xhtml</source>  
  6.    </tag>  
  7. </facelet-taglib>  

Aside from pointing Facelets at your new taglib XML file, that's it. You may add as many tags as you want to your new taglib. By specifying the http://www.mycompany.com/jsf namespace within your pages, you can now write:

  1. <!-- include-tag.xhtml -->  
  2. ...   
  3.   
  4. <span id="leftNav">  
  5.    <my:siteNav menuBean="#{backingBean.options}"/>  
  6. </span>  
  7. ...  

The include-tag.xhtml example is equivalent to the include.xhtml example above. The attribute menuBean will be made available as an attribute within siteNav.xhtml, just as <ui:param/> provided.

Your project may include a whole library of custom tags that are packaged with your JAR files or simply placed within a folder in your web application. Many more tags are covered in the Facelets Developer Documentation.

分享到:
评论
4 楼 hintcnuie 2008-12-15  
好像是没有org/apache/commons/lang/builder/HashCodeBuilder这个类吧?你把apache的collection工具类的jar到导进去试一下啊
3 楼 Arron.li 2008-12-15  
hintcnuie 写道

没用过tree2的组件,恐怕没法给你建议了,不过你可以把错误消息贴出来,一起看看

exception

javax.servlet.ServletException: org/apache/commons/lang/builder/HashCodeBuilder
javax.faces.webapp.FacesServlet.service(FacesServlet.java:154)
org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:301)


root cause

java.lang.NoClassDefFoundError: org/apache/commons/lang/builder/HashCodeBuilder
org.apache.myfaces.renderkit.html.util.DefaultAddResource$ScriptPositionedInfo.hashCode(DefaultAddResource.java:639)
java.util.HashMap.hash(HashMap.java:264)
java.util.HashMap.put(HashMap.java:382)
java.util.HashSet.add(HashSet.java:194)
org.apache.myfaces.renderkit.html.util.DefaultAddResource.addPositionedInfo(DefaultAddResource.java:302)
org.apache.myfaces.renderkit.html.util.DefaultAddResource.addJavaScriptAtPosition(DefaultAddResource.java:210)
org.apache.myfaces.renderkit.html.util.DefaultAddResource.addJavaScriptAtPosition(DefaultAddResource.java:122)
org.apache.myfaces.renderkit.html.util.DefaultAddResource.addJavaScriptAtPosition(DefaultAddResource.java:140)
org.apache.myfaces.custom.tree2.HtmlTreeRenderer.encodeJavascript(HtmlTreeRenderer.java:632)
org.apache.myfaces.custom.tree2.HtmlTreeRenderer.encodeBegin(HtmlTreeRenderer.java:161)
javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:515)
org.apache.myfaces.custom.tree2.UITreeData.encodeBegin(UITreeData.java:254)
com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:232)
com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:239)
com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:580)
org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:41)
org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:132)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:140)
org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:301)

2 楼 hintcnuie 2008-12-11  
没用过tree2的组件,恐怕没法给你建议了,不过你可以把错误消息贴出来,一起看看
1 楼 Arron.li 2008-12-10  
我这几天一直研究facelets、tomahawk整合,不过在xhtml一直不能使用tree2组件
不知楼主有什么好建议
我所用的jar如下:
jsf-facelets-1.1.11.jar
jsf-api-1.1_02.jar
jsf-impl-1.1_02.jar
myfaces-api-1.1.5.jar
myfaces-impl-1.1.5.jar
tomahawk-1.1.8.jar

相关推荐

    facelets 教程

    #### 三、Facelets 与 AJAX:完美的搭档 随着 Web 2.0 的兴起,AJAX(Asynchronous JavaScript and XML)技术成为构建富互联网应用程序的关键。然而,AJAX 的实现往往伴随着服务器端与客户端之间复杂的交互逻辑。...

    facelets_demo

    Facelets 是一种用于构建用户界面的视图技术,主要在JavaServer Faces (JSF) 应用程序中使用。它提供了声明式的方式去定义页面结构和逻辑,使得开发者能够更高效地创建和维护Web应用程序的前端。在这个"facelets_...

    facelets源码包

    - **组件库(Component Library)**: Facelets可以使用JSF的内置组件,也可以添加第三方组件库,如PrimeFaces或RichFaces。 - **EL(Expression Language)**: Facelets与EL紧密集成,可以方便地访问后台Bean的...

    facelets中文教程(初级+高级)

    - Facelets模板允许开发者创建可重用的页面布局和设计元素。通过定义模板和模板客户,可以实现代码复用,提高开发效率。 3. **Facelets表达式语言(EL)** - EL是Facelets中用于访问应用程序上下文数据的简便语法。...

    JSF与Facelets应用程序

    7. **Facelets模板和组件**: Facelets的模板系统允许创建可重用的布局和组件,提高了代码的复用性和一致性。开发者可以创建一个母版页,然后在子页面中继承和扩展。 8. **整合其他技术**: JSF可以与其他Java EE技术...

    Facelets Essentials - APRESS

    1. **模板化**:Facelets支持模板化,允许开发者定义可重用的UI片段,这极大地提高了代码的复用性和维护性。 2. **组件化**:Facelets采用了组件化的思想,使得UI组件的定义更加清晰,易于理解和管理。 3. **性能...

    Apress - Definitive Guide To Apache Myfaces And Facelets (2008)

    综上所述,《Apress - Definitive Guide To Apache Myfaces And Facelets (2008)》这本书不仅为开发者提供了全面的技术指导,而且还深入探讨了许多实用技巧和最佳实践。无论是初学者还是有一定经验的开发者,都能...

    facelets.......................................

    3. **Facelets模板**: - **模板组件**:Facelets中的模板组件可以定义页面的重复结构,如页眉、页脚和侧边栏。 - **模板客户**:模板客户可以引用模板组件,实现页面布局的重用。 4. **布局文件解析**: - `...

    Facelets:jsf、primefaces、facelets、spring 集成、jstl、

    Facelets 提供了模板、组合和重用功能,使得开发更加模块化和易于维护。与JSP相比,Facelets 更加轻量级,有更好的性能和更少的冗余代码。 **PrimeFaces** PrimeFaces 是一个流行的开源JSF组件库,提供了大量的UI...

    WebApplicationFacelets-源码.rar

    本篇文章将深入探讨Facelets的核心概念、架构以及源码分析,帮助读者理解其内部工作原理。 一、Facelets简介 Facelets作为JSF的视图层技术,它取代了JSP成为JSF2.0及更高版本的默认视图表示语言。Facelets提供了更...

    WebApplicationFacelets:与 WebApplication 相同,但带有 facelets ..

    此外,运行示例应用并进行调试也是深入理解Facelets工作原理的好方法。 总的来说,WebApplicationFacelets是一个强调使用Facelets技术的Web应用示例,对于想要学习和掌握Java Web开发,特别是JSF和Facelets的开发者...

    深入掌握J2EE编程技术

    了解JSF组件库、Facelets模板语言和EL表达式对于创建交互式Web应用至关重要。 5. **CDI(Contexts and Dependency Injection)**:CDI是Java EE中的依赖注入(DI)规范,使得组件间的关系可以自动管理,提高代码的...

    jsf仿frame

    提供的压缩包文件很可能包含了实现这一功能的完整代码示例,包括JSF的配置文件(faces-config.xml)、Facelets模板文件(.xhtml)、Java后台bean(用于处理请求和业务逻辑)以及可能的样式表(CSS)和脚本...

    jsf-api,java前台页面技术

    标签在JSF中扮演着重要的角色,它们是UI组件的声明式表示,允许在Facelets模板中使用。JSF提供了大量的内建标签,如`&lt;h:inputText&gt;`用于创建文本输入字段,`&lt;h:commandButton&gt;`用于创建提交按钮。同时,开发者还可以...

    java培训课程-JBOSS-SEAM开发.pptx

    通过这个Java培训课程,开发者将深入了解如何利用JBOSS SEAM和Facelets进行高效的企业级应用开发,理解其背后的设计理念和技术优势,从而提升开发质量和效率。课程内容详实,覆盖了从理论到实践的各个环节,对于希望...

    推荐经典《JSF入门》简体中文版教程

    与JSP相比,Facelets更易于维护,支持模板和组件重用。在Facelets中,开发者可以使用XML语法定义UI组件和布局,同时支持EL(Expression Language)表达式,方便数据绑定。 三、Managed Beans Managed Beans是JSF中...

    myfaces-core-1.2.2-src.zip

    - 分析Facelets的编译过程,理解如何将Facelets模板转化为JavaServer Pages。 - 查看组件模型的实现,了解组件生命周期和渲染过程。 - 研究EL的解析和求值逻辑,提高对EL表达式的理解和运用。 - 深入理解JSF生命周期...

    JSF入门.doc

    在《JSF入门》这本书中,你将学习如何设置JSF环境,创建第一个JSF应用程序,了解Facelets模板,掌握Managed Beans的使用,以及如何进行数据验证和事件处理。此外,书中还会涉及JSF与Servlet、JSP的比较,以及如何在...

    《JSF入门》简体中文版

    JSF组件通过XML标记在Facelets模板中声明,每个组件都有一个唯一的标识符(ID),可以绑定到后台的JavaBean属性。组件可以有子组件,并可以触发和监听事件。 ### 5. EL(Expression Language) EL是JSF中用于访问...

Global site tag (gtag.js) - Google Analytics