The ICEfaces Tutorial
Table of Contents


Lesson:Using facelets

ICEfaces Facelets Tutorial

Facelets is a view technology that focuses on building JSF component trees. Facelets steps outside of the JSP specification and provides a highly performant, JSF-centric view technology. Facelets includes many features such as:

This tutorial will discuss the following topics:

 

Configuring/Installing Facelets

The steps to get facelets configured/installed are as follows:

  1. Download the latest ICEfaces distribution.
  2. Make sure the icefaces-facelets jar is included in your project lib folder.
  3. Add the Facelet init parameter to the web.xml file.
  4. Add the FaceletsViewHandler to the faces-config.xml file

The latest ICEfaces distribution can be found at http://www.icefaces.org

The following code should be included in the web.xml file:

          ...
          <context-param>
            <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
 	    <param-value>.jspx</param-value>
          </context-param>
          ...
      

The above code is used to notify JSF to assume a prefix of jspx, which the facelet's renderer can interpret. Note that the .jspx value can be .xhtml or which ever file extension you require.

The following code should be included in the faces-config.xml file:

          ...
          <application>
            <view-handler>
                com.icesoft.faces.facelets.D2DFaceletViewHandler
            </view-handler>
          </application>
          ...
      

This includes the Facelets view handler. This handles the Render Response and Restore View phases of the JSF request-processing life cycle.

 

How to Use Facelets Templating

Facelets emphasizes its ability to template content in your application. Templating promotes re-use and eases long term maintenance of your application, allowing content to be changed in one spot, but used in multiple pages.

When describing templating within Facelets, we have two roles: the template and the template client. Any document can act as a template; but what makes a document a template? It just simply uses one or more <ui:insert/> tags to inject some content from another source. The other half of the equation is the template client. This includes documents that use the <ui:component/>, <ui:composition/> , <ui:fragment/>, or <ui:define/>. These tags and their uses will be described in greater detail below.

For our example, we have developed a site that uses Facelets templating techniques. The site is divided into four parts, header, footer, navigation, and content sections. Each page on the site is run off of the main-template.jspx template shown below:

          ...
          <div class="page">
            <div class="header">
                <ui:include src="/WEB-INF/inc-content/header.jspx"/>
            </div>
            <div class="navigation">
                <ui:include src="/WEB-INF/inc-content/navigation.jspx"/>
            </div>
            <div class="content">
                <ui:insert name="content">
                     Default Content
                </ui:insert>
            </div>
            <div class="footer">
                <ui:include src="/WEB-INF/inc-content/footer.jspx"/>
            </div>
        </div>
        ...
      

The header, footer, and navigation is included directly into the template. The content section is constantly changing therefore it isn't included directly in the template.

The content pages use another template to outline its content. The content-template.jspx source code is shown below:

          <div vxmlns="http://www.w3.org/1999/xhtml"
               xmlns:ui="http://java.sun.com/jsf/facelets">

            <div class="main-header">
                <h3><ui:insert name="pageName"/></h3>
            </div>
            <div class="page-container-header">
                <ui:insert name="pageContent"/>
            </div>
          </div>
      

The content template defines a header and the page content. This will mean that each page that uses the template will have a header and the content sections.

The following is an examle of a content page:

          <ui:composition template="WEB-INF/inc-templates/main-template.jspx"
                             xmlns="http://www.w3.org/1999/xhtml"
                             xmlns:ui="http://java.sun.com/jsf/facelets"
                             xmlns:f="http://java.sun.com/jsf/core">

            <!-- params for page titles-->
            <ui:param name="pageTitle" value="UI Component Tag" />
            <ui:param name="contentHeader" value="UI Component Tag Reference"/>

            <ui:define name="content">

                <ui:decorate template="/WEB-INF/inc-templates/content-template.jspx">

                    <!-- header content here  -->
                    <ui:define name="pageName">
                        #{contentHeader}
                    </ui:define>

                    <!-- insert content here -->
                    <ui:define name="pageContent">
                        <ui:include src="/WEB-INF/inc-content/component-content.jspx"/>
                    </ui:define>
                </ui:decorate>

            </ui:define>
          </ui:composition>
      

This page uses a ui:composition tag which is linked to the main-template tenplate. This will include the header, footer, and navigation pages and allow the content to be defined separetly. The content pages also use a ui:decorate tag to link the content template to the page. The page content is defined on another jspx page which is included with an ui:include tag.

Download the demo:

 

How Compositions and Decorations Work

The composition and decorate tags are very similar in the fact that they both wrap content to be included in another Facelet. The composition tag will not display any content outside of the <ui:composition/> tag. Any content inside the tag will be included when another Facelets page includes the page containing the composition tag. The following is an example of how the composition tag works:

          template.jsf
          <h2><ui:insert name="title".></h2>
          
          composition.jsf
          This text will be ignored.
          <ui:composition template="template.jsf">
                <ui:define name="title">Hello World!</ui:define>
          </ui:composition>
          This text will be ignored.
          
          HTML Output
          <h2>Hello World!</h2>
      

The decorate tag is handled a little differently. Any content outside of the UI Decorate tag will be displayed by the Facelets view handler. Any content within the decorate tag will be passed to the associated template as parameters or simply ignored. Also nested ui:define tags can be used to pass names content to the associated template. The following is an example of how the decorate tag works:

          template.jsf
          This text will be removed.
          <ui:composition>
              <h2><ui:insert name="title"/></h2>
              <ui:insert name="body"/>
          </ui:composition>   
          This text will be removed.
          
          decorate.jsf
          Text before will stay.
          <ui:decorate template="template.jsf">
              <ui:define name="title">Our Products</ui:define>
              <ui:define name="body">
                 <ul>
                    <li>Apples</li>
                    <li>Oranges</li>
                    <li>Bananas</li>
                 </ul>
              </ui:define>
          </ui:decorate>
          Text after will stay.
          
          HTML Output
          Text before will stay.
          <h2>Our Products</h2>
              <ul>
                 <li>Apples</li>
                 <li>Oranges</li>
                 <li>Bananas</li>
              </ul>
          Text after will stay.
      
 

How to Use Insert and Define Tags

The insert tag is a templating tag that declares a named content element to be defined by another Facelet. It can be used effectively with the ui:define tag to pass values between facelets. The define tag is a templating tag that defines named content to be inserted into a template. The name attribute value must match that of a ui:insert tag in the target template for the named content to be included. The following is an example on how the two tags work in conjunction with each other:

          content-template.jspx
          ...
          <div class="main-header">
             <h3><ui:insert name="pageName"/></h3>
          </div>
          ...
           
          component.jspx
          ...
          <!-- header content here  -->
          <ui:define name="pageName">
              #{contentHeader}
          </ui:define>
          ... 
      
 

How to Use Dynamic Includes (ui:include)

The include tag is a server-side include tag for Facelets. It simply includes the document pointed to by the ?src? attribute as part of the current JSF page. The included document should use a component or composition tag to trim unnecessary markup, or it may simply contain a fragment of XHTML or XML to be included.

For dynamic includes the ?src? attribute is linked to a backing bean value. When the navigation is changed (user clicks a new link), the backing bean value us also changed thus changing the include value. This enables the use of a single include tag to be used in the template. The following is an example of how it can be basically used:

          ...
          <div class="header">
            <ui:include src="/WEB-INF/inc-content/header.jspx"/>
          </div>
          ...
      

The following code shows how the include tag can be used for dynamically including content:

          ...
          <ui:include src="#{navigation.selectedPanel.menuContentInclusionFile}"/>
          ...
      

For more information on dynamic includes using Facelets see the Dynamic-Includes Tutorial located here.

 

Defining a Custom Facelets Component

Facelets is not only just used for templates. You can create your own custom tags to be used in your application. Creating your own custom tags can be beneficial due to it will promote code re-use and portability. For our example we have a register form, it consists of a few labels and a few input text boxes. Normally this would take quite a few lines of code to create:

          ...
          <ice:panelGrid columns="2">
              <ice:outputLabel value="Name:"/>
              <ice:inputText value="#{input.name}"/>
              <ice:outputLabel value="Address:"/>
              <ice:inputText value="#{input.address}"/>
              <ice:outputLabel value="Phone:"/>
              <ice:inputText value="#{input.phone}"/>
              <ice:outputLabel value="Email:"/>
              <ice:inputText value="#{input.email}"/>
              <ice:outputLabel value="City:"/>
              <ice:inputText value="#{input.city}"/>
              <ice:outputLabel value="Province/State:"/>
              <ice:inputText value="#{input.provState}"/>
              <ice:outputLabel value="Postal/Zip Code:"/>
              <ice:inputText value="#{input.postalZip}"/>
          </ice:panelGrid>    
          ...
      

The following code renders a similar output using the custom component we have created:

          <c:forEach var="inputField" items="#{inputFieldManager.fields}">
              <ft:inputField value="#{inputField}"/>
          </c:forEach>
      

Notice the big difference in the amount of code? The second example is getting the information from the backing bean. The nice thing about doing it this was is say if there was a search or edit page, the form used would probably be similar. Instead of re writing the same code all over again we can use our custom component.

 

Steps to Create a Custom Component

There are three major steps in creating a custom component:

  1. Create a Facelets tag library.
  2. Declare the tag library in web.xml.
  3. Import the tagfile using namespace.
 

Step 1: Create a Facelets tag library

A tagfile is a file that follows the facelet_taglib_1_0.dtd. It is similar in concept to a TLD file in JSP. The following is an example of the tag library:

          <facelet-taglib>
              <namespace>http://www.facelettutorial.com/jsf</namespace>
              <tag>
                <tag-name>inputField</tag-name>
                <source>../../inc-templates/inputField-component.jspx</source>
              </tag>
          </facelet-taglib>
      

The faceletsTutorial Tag library only defines one tag but all of the tags being used in the application should be defined in the same tag library file. Note the namespace element that is declared before the tag element, it will be used in the facelets page.

 

Step 2: Declare the tag library in web.xml

This will tell Facelets the that tag library exists so it can use it. The following is how it should be declared:

          ...
          <context-param>
              <param-name>facelets.LIBRARIES</param-name>
              <param-value>
                  /WEB-INF/facelets/tags/faceletsTutorial.taglib.xml
              <param-value>
          </context-param>
          ...
      

Note you can also define multiple tag libraries to be used by passing facelets.LIBRARIES as a semicolon-delimited list.

 

Step 3: Import the tagfile using namespace

Once the tagfile has been created and defined in the tag library its ready to be used. To use the tagfile, declare it as an XML namespace, shown below:

          <div xmlns:ft="http://www.facelettutorial.com/jsf">
          ...
                <ft:inputField value="#{inputField}"/>
          ...      
      
 

Example that use Facelets

Example Source Notes
Component-Showcase-Facelets Available in release bundles The Component Showcase Facelets version demonstrates how ICEfaces components are compatable with Facelets.
Facelets-Tutorial facelets-tutorial source code Basic site example on how to use Facelets. Includes samples on templating and custom components.

The ICEfaces Tutorial
Table of Contents

Copyright 2006 ICEsoft Technologies Inc. All rights reserved.