Facelets Components in JSF 1.2

Exclusive offer: get 50% off this eBook here
JSF 1.2 Components

JSF 1.2 Components — Save 50%

Develop advanced Ajax-enabled JSF applications

$26.99    $13.50
by | November 2009 | Java

In this article Ian Hlavats, we are going to discuss:

  • Creating a Facelets UI composition template
  • Decorating the user interface
  • Rendering a UI fragment
  • An advanced Facelets composition template

 

One of the more advanced features of the Facelets framework is the ability to define complex templates containing dynamic nested content.

What is a template?
The Merriam-Webster dictionary defines the word "template" as "a gauge, pattern, or mold (as a thin plate or board) used as a guide to the form of a piece being made" and as "something that establishes or serves as a pattern." In the context of user interface design for the Web, a template can be thought of as an abstraction of a set of pages in the web application.
A template does not define content, but rather it defines placeholders for content, and provides the layout, orientation, flow, structure, and logical organization of the elements on the page. We can also think of templates as documents with "blanks" that will be filled in with real data and user interface controls at request time. One of the benefits of templating is the separation of content from presentation, making the maintenance of the views in our web application much easier.

The <ui:insert> tag has a name attribute that is used to specify a dynamic content region that will be inserted by the template client. When Facelets renders a UI composition template, it attempts to substitute any <ui:insert> tags in the Facelets template document with corresponding <ui:define> tags from the Facelets template client document. Conceptually, the Facelets composition template transformation process can be visualized as follows:

JSF 1.2 Components

In this scenario, the browser requests a Facelets template client document in our JSF application. This document contains two <ui:define> tags that specify named content elements and references a Facelets template document using the <ui:composition> tag's template attribute. The Facelets template document contains two <ui:insert> tags that have the same names as the <ui:define> tags in the client document, and three <ui:include> tags for the header, footer, and navigation menu.

This is a good example of the excellent support that Facelets provides for the Composite View design pattern. Facelets transforms the template client document by merging any content it defines using <ui:define> tags with the content insertion points specified in the Facelets template document using the <ui:insert> tag. The result of merging the Facelets template client document with the Facelets template document is rendered in the browser as a composite view.

While this concept may seem a bit complicated at first, it is actually a powerful feature of the Facelets view defi nition framework that can greatly simplify user interface templating in a web application. In fact, the Facelets composition template document can itself be a template client by referencing another composition template. In this way, a complex hierarchy of templates can be used to construct a flexible, multi-layered presentation tier for a JSF application.

Without the Facelets templating system, we would have to copy and paste view elements such as headers, footers, and menus from one page to the next to achieve a consistent look and feel across our web application. Facelets templating enables us to define our look and feel in one document and to reuse it across multiple pages. Therefore, if we decide to change the look and feel, we only have to update one document and the change is immediately propagated to all the views of the JSF application.

Let's look at some examples of how to use the Facelets templating feature.

A simple Facelets template

The following is an example of a simple Facelets template. It simply renders a message within an HTML <h2> element. Facelets will replace the "unnamed" <ui:insert> tag (without the name attribute) in the template document with the content of the <ui:composition> tag from the template client document.

template01.jsf
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Facelets template example</title>
<link rel="stylesheet" type="text/css" href="/css/style.css" />
</head>
<body>
<h2><ui:insert /></h2>
</body>
</html>

A simple Facelets template client

Let's look at a simple example of Facelets templating. The following page is a Facelets template client document. (Remember: you can identify a Facelets template client by looking for the existence of the template attribute on the <ui:composition> tag.) The <ui:composition> tag simply contains the text Hello World.

templateClient01.jsf
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ui:composition example</title>
</head>
<body>
<ui:composition template="/WEB-INF/templates/template01.jsf">
Hello World
</ui:composition>
<ui:debug />
</body>
</html>

The following screenshot displays the result of the Facelets UI composition template transformation when the browser requests templateClient01.jsf.

JSF 1.2 Components

Another simple Facelets template client

The following Facelets template client example demonstrates how a template can be reused across multiple pages in the JSF application:

templateClient01a.jsf
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ui:composition example</title>
</head>
<body>
<ui:composition template="/WEB-INF/templates/template01.jsf">
How are you today?
</ui:composition>
<ui:debug />
</body>
</html>

The following screenshot displays the result of the Facelets UI composition template transformation when the browser requests templateClient01a.jsf:

JSF 1.2 Components

A more complex Facelets template

The Facelets template in the previous example is quite simple and does not demonstrate some of the more advanced capabilities of Facelets templating. In particular, the template in the previous example only has a single <ui:insert> tag, with no name attribute specified. The behavior of the unnamed <ui:insert> tag is to include any content in the referencing template client page.

In more complex templates, multiple <ui:insert> tags can be used to enable template client documents to defi ne several custom content elements that will be inserted throughout the template. The following Facelets template document declares three named <ui:insert> elements. Notice carefully where these tags are located.

template02.jsf
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><ui:insert name="title" /></title>
<link rel="stylesheet" type="text/css" href="/css/style.css" />
</head>
<body>
<ui:include src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="/WEB-INF/includes/header.jsf" />
<h2><ui:insert name="header" /></h2>
<ui:insert name="content" />
<ui:include src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="/WEB-INF/includes/footer.jsf" />
</body>
</html>

In the following example, the template client document defines three content elements named title, header, and content using the <ui:define> tag. Their position in the client document is not important because the template document determines where this content will be positioned.

templateClient02.jsf
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ui:composition example</title>
</head>
<body>
<ui:composition template="/WEB-INF/templates/template02.jsf">
<ui:define name="title">Facelet template example</ui:define>
<ui:define name="header">Hello World</ui:define>
<ui:define name="content">Page content goes here.</ui:define>
</ui:composition>
<ui:debug />
</body>
</html>

The following screenshot displays the result of a more complex Facelets UI composition template transformation when the browser requests the page named templateClient02.jsf.

JSF 1.2 Components

The next example demonstrates reusing a more advanced Facelets UI composition template. At this stage, we should have a good understanding of the basic concepts of Facelets templating and reuse.

templateClient02a.jsf
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ui:composition example</title>
</head>
<body>
Facelets Components
[ 78 ]
<ui:composition template="/WEB-INF/templates/template02.jsf">
<ui:define name="title">Facelet template example</ui:define>
<ui:define name="header">Thanks for visiting!</ui:define>
<ui:define name="content">We hope you enjoyed our site.</ui:define>
</ui:composition>
<ui:debug />
</body>
</html>

The next screenshot displays the result of the Facelets UI composition transformation when the browser requests templateClient02a.jsf. We can follow this pattern to make a number of JSF pages reuse the template in this manner to achieve a consistent look and feel across our web application.

JSF 1.2 Components

Decorating the user interface

The Facelets framework supports the definition of smaller, reusable view elements that can be combined at runtime using the Facelets UI tag library. Some of these tags, such as the <ui:composition> and <ui:component> tags, trim their surrounding content. This behavior is desirable when including content from one complete XHTML document within another complete XHTML document.

There are cases, however, when we do not want Facelets to trim the content outside the Facelets tag, such as when we are decorating content on one page with additional JSF or HTML markup defi ned in another page.

For example, suppose there is a section of content in our XHTML document that we want to wrap or "decorate" with an HTML <div> element defined in another Facelets page. In this scenario, we want all the content on the page to be displayed, and we are simply surrounding part of the content with additional markup defined in another Facelets template. Facelets provides the <ui:decoration> tag for this purpose.

Decorating content on a Facelets page

The following example demonstrates how to decorate content on a Facelets page with markup from another Facelets page using the <ui:decoration> tag. The <ui:decoration> tag has a template attribute and behaves like the <ui:composition> tag. Facelets templating typically uses the <ui:composition>. It references a Facelets template document that contains markup to be included in the current document. The main difference between the <ui:composition> tag and the <ui:decoration> tag is that Facelets trims the content outside the <ui:composition> tag but does not trim the content outside the <ui:decoration> tag.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ui:decorate example</title>
<link rel="stylesheet" type="text/css" href="css/style.css" />
</head>
<body>
Text before will stay.
<ui:decorate template="/WEB-INF/templates/box.jsf">
<span class="header">Information Box</span>
<p>This is the first line of information.</p>
<p>This is the second line of information.</p>
<p>This is the third line of information.</p>
</ui:decorate>
Text after will stay.
<ui:debug />
</body>
</html>

Creating a Facelets decoration

Let's examine the Facelets decoration template referenced by the previous example. The following source code demonstrates how to create a Facelets template to provide the decoration that will surround the content on another page.

As we are using a <ui:composition> tag, only the content inside this tag will be used. In this example, we declare an HTML <div> element with the "box" CSS style class that contains a single Facelets <ui:insert> tag. When Facelets renders the above Facelets page, it encounters the <ui:decorate> tag that references the box.jsf page. The <ui:decorate> tag will be merged together with the associated decoration template and then rendered in the view. In this scenario, Facelets will insert the child content of the <ui:decorate> tag into the Facelets decoration template where the <ui:insert> tag is declared.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jstl/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Box</title>
</head>
<body>
<ui:composition>
<div class="box">
<ui:insert />
</div>
</ui:composition>
</body>
</html>

The result is that our content is surrounded or "decorated" by the <div> element. Any text before or after the <ui:decoration> is still rendered on the page, as shown in the next screenshot:

JSF 1.2 Components

The included decoration is rendered as is, and is not nested inside a UI component as demonstrated in the following Facelets debug page:

JSF 1.2 Components

JSF 1.2 Components Develop advanced Ajax-enabled JSF applications
Published: November 2009
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

Rendering a UI fragment

Like the <ui:decorate> tag, the <ui:fragment> tag is also a non-trimming tag. Facelets preserves the markup outside this tag.

One difference between the <ui:decoratition> and the <ui:fragment> tags, however, is that Facelets includes the content of the <ui:fragment> tag inside a UI component. In this way, the <ui:fragment> and the <ui:component> tag have similar behavior.

Another difference between the <ui:decorate> and the <ui:fragment> tags is that the <ui:fragment> tag does not support the template attribute, but instead has a binding attribute that gives us the ability to bind the tag to a UI component in our backing bean.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ui:fragment example</title>
</head>
<body>
<h:form>
Text before will be rendered.
<ui:fragment>
<p>A fragment adds a component to the view but does not trim any
content.</p>
</ui:fragment>
Text after will be rendered.
<ui:debug />
</h:form>
</body>
</html>

JSF 1.2 Components

The non-trimming and UI component-based behavior of the <ui:fragment> tag is demonstrated in the Facelets debug page shown in the next screenshot.

As Facelets renders the content of the <ui:fragment> tag within a UI component, we can use this tag whenever we want to group multiple components (and markup) together as a single UI component, such as within the <h:panelGrid> and <f:facet> tags.

JSF 1.2 Components

An advanced Facelets composition template

The following example demonstrates an advanced Facelets composition template and uses the majority of Facelets tags in a single composite view. In this example, the template client document specifies a number of named content elements using the <ui:define> tag and reuses multiple UI elements.

The <ui:define> tag named title specifies the document title. The links element uses a <ui:include> tag to include the navigation menu that will be inserted into the links section of the template. The header element simply defines the page header. The content element defines the paragraph text to be rendered by the template. Finally, the data element defines the data to be displayed by re-using the external links.jsf template that renders a parameterized list of customers.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Facelets template example</title>
</head>
<body>
<ui:composition template="/WEB-INF/templates/template03.jsf">
<ui:define name="title">Facelets template example</ui:define>
<ui:define name="links">
<ui:include src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="/WEB-INF/includes/links.jsf" />
</ui:define>
<ui:define name="header">Customer Listing</ui:define>
<ui:define name="content">
<p>Our company has #{customerBean.customerCount} customers.</p>
<p>They have been separated into two lists shown below.</p>
</ui:define>
<ui:define name="data">
<h:panelGrid columns="2">
<ui:fragment>
<ui:include src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="/WEB-INF/includes/customerList.jsf">
<ui:param name="title" value="Male Customers" />
<ui:param name="customers" value="#{customerBean.
maleCustomers}" />
</ui:include>
</ui:fragment>
<ui:fragment>
<ui:include src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="/WEB-INF/includes/customerList.jsf">

<ui:param name="title" value="Female Customers" />
<ui:param name="customers" value="#{customerBean.
femaleCustomers}" />
</ui:include>
</ui:fragment>
</h:panelGrid>
</ui:define>
</ui:composition>
</body>
</html>

The corresponding Facelets UI composition template for this example uses te <ui:include> tag to render a header defined in an external Facelets page. The main content of the page is rendered using the <h:panelGrid> tag to render a single-column layout table. (CSS-based layouts are generally preferred to table-based layouts; this example is for demonstration only.)

The first row of the panel grid renders the links element by using the <ui:insert> tag named links. Notice that the content is wrapped in a <ui:fragment> tag to ensure that any included content is wrapped with a single UI component so the content is rendered in a single column within the panel grid component.

The second row of the panel grid renders a title inside the HTML <h2> element. The third row of the panel grid renders a box decoration around the named data element provided by the template client. The page footer is rendered using a <ui:include> tag.

Finally, we declare the <ui:debug> tag and set the rendered attribute to true based on the value of the facelets.DEVELOPMENT initialization parameter. This way, debugging support can be enabled conditionally whenever Facelets error handling is turned on during the development cycle.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><ui:insert name="title" /></title>
<link rel="stylesheet" type="text/css" href="/chapter2/css/style.css"
/>
</head>
<body>
<ui:include src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="/WEB-INF/includes/header.jsf" />
<h:panelGrid width="100%">
<ui:fragment>
<ui:insert name="links" />
</ui:fragment>
<ui:fragment>
<h2><ui:insert name="header" /></h2>
<ui:insert name="content" />
</ui:fragment>
<ui:fragment>
<ui:decorate template="/WEB-INF/templates/box.jsf">
<ui:insert name="data" />
</ui:decorate>
</ui:fragment>
</h:panelGrid>
<ui:include src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="/WEB-INF/includes/footer.jsf" />
<ui:debug hotkey="D" rendered="#{initParam['facelets.DEVELOPMENT']}"
/>
</body>
</html>

The result of the Facelets UI composition transformation is a complex composite view arrangement containing multiple reusable UI elements, such as headers, footers, navigation menus, and box decorations.

JSF 1.2 Components

Summary

In this article, we explored how the Facelets view definition framework can be used to enhance presentation tier development in a JSF application.

We looked at a brief history of web development on the Java platform and compared Facelets with JSP technology to understand the advantages that Facelets offers to the JSF developer.

Facelets provides a fresh and compelling alternative to JSP as the view technology for JSF. Designed specifically to support the UI component tree lifecycle, Facelets is a highly optimized technology that greatly simplifies user interface development with the JSF framework.

Facelets pages are different from JSP pages because they are not compiled to generate servlets and they do not contain JSP expressions and directives. JSF tag libraries can be included in Facelets pages by using XML namespaces. Faceletsand JSP (since JSP 2.0) both support inline JSF EL expressions.

Our discussion included tips on how to configure a JSF application to use Facelets by specifying initialization parameters in web.xml and by configuring JSF to use the Facelets ViewHandler implementation in faces-config.xml. We can enable the Facelets refresh behavior during development, and disable it in production for best performance.

We studied examples of how to perform common tasks with the Facelets framework, such as enabling detailed error reporting with line number and attribute information, examining the UI component tree at runtime, iterating data in a Facelets page, including components and markup, removing components and markup, and decorating content in a Facelets page. We also looked at how to render advanced UI composition templates using the Facelets framework. Facelets templates can be reused by multiple client documents, simplifying the task of implementing a consistent look and feel across all the pages in our JSF application.

Based on the Composite View design pattern, Facelets is a sophisticated framework that makes it easy to create reusable user interface elements for a JSF application. Facelets supports a declarative approach to component-based development.

JSF 1.2 Components Develop advanced Ajax-enabled JSF applications
Published: November 2009
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

About the Author :


Books From Packt

GlassFish Administration
GlassFish Administration

JBoss AS 5 Development
JBoss AS 5 Development

Spring Persistence with Hibernate
Spring Persistence with Hibernate

Tomcat 6 Developer's Guide
Tomcat 6 Developer's Guide

RESTful Java Web Services
RESTful Java Web Services

ICEfaces 1.8: Next Generation Enterprise Web Development
ICEfaces 1.8: Next Generation Enterprise Web Development

JBoss RichFaces 3.3
JBoss RichFaces 3.3

Apache Maven 2 Effective Implementation
Apache Maven 2 Effective Implementation

No votes yet
This article helped me tremendously in understanding a problem by
Thanks for posting this. It helped me understand AND FIX a rendering problem that I had with a template. If I had found this article three days ago, I would have saved a lot of time.

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Z
U
n
g
6
G
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software