Introduction to Facelets

We are working on a fresh, updated Jakarta EE Tutorial. This section hasn’t yet been updated.

The term Facelets refers to the view declaration language for Jakarta Faces technology. Facelets is a part of the Jakarta Faces specification and also the preferred presentation technology for building Jakarta Faces technology–based applications. Jakarta Server Pages technology, previously used as the presentation technology for Jakarta Faces, does not support all the new features available in Jakarta Faces in the Jakarta EE platform. Jakarta Server Pages technology is considered to be a deprecated presentation technology for Jakarta Faces.

What Is Facelets?

Facelets is a powerful but lightweight page declaration language that is used to build Jakarta Faces views using HTML style templates and to build component trees. Facelets features include the following:

  • Use of XHTML for creating web pages

  • Support for Facelets tag libraries in addition to Jakarta Faces and JSTL tag libraries

  • Support for the Expression Language (EL)

  • Templating for components and pages

The advantages of Facelets for large-scale development projects include the following:

  • Support for code reuse through templating and composite components

  • Functional extensibility of components and other server-side objects through customization

  • Faster compilation time

  • Compile-time EL validation

  • High-performance rendering

In short, the use of Facelets reduces the time and effort that needs to be spent on development and deployment.

Facelets views are usually created as XHTML pages. Jakarta Faces implementations support XHTML pages created in conformance with the XHTML Transitional Document Type Definition (DTD), as listed at https://www.w3.org/TR/xhtml1/#a_dtd_XHTML-1.0-Transitional. By convention, web pages built with XHTML have an .xhtml extension.

Jakarta Faces technology supports various tag libraries to add components to a web page. To support the Jakarta Faces tag library mechanism, Facelets uses XML namespace declarations. Tag Libraries Supported by Facelets lists the tag libraries supported by Facelets.

Tag Libraries Supported by Facelets
Tag Library URI Prefix Example Contents

Jakarta Faces Facelets Tag Library

jakarta.faces.facelets

ui:

ui:component

ui:insert

Tags for templating

Jakarta Faces HTML Tag Library

jakarta.faces.html

h:

h:head

h:body

h:outputText

h:inputText

Jakarta Faces component tags for all UIComponent objects

Jakarta Faces Core Tag Library

jakarta.faces.core

f:

f:actionListener

f:attribute

Tags for Jakarta Faces custom actions that are independent of any particular render kit

Pass-through Elements Tag Library

jakarta.faces

faces:

faces:id

Tags to support HTML5-friendly markup

Pass-through Attributes Tag Library

jakarta.faces.passthrough

p:

p:type

Tags to support HTML5-friendly markup

Composite Component Tag Library

jakarta.faces.composite

cc:

cc:interface

Tags to support composite components

JSTL Core Tag Library

jakarta.tags.core

c:

c:forEach

c:catch

JSTL 1.2 Core Tags

JSTL Functions Tag Library

jakarta.tags.functions

fn:

fn:toUpperCase

fn:toLowerCase

JSTL 1.2 Functions Tags

Facelets provides two namespaces to support HTML5-friendly markup. For details, see HTML5-Friendly Markup.

Facelets supports tags for composite components, for which you can declare custom prefixes. For more information on composite components, see Composite Components.

The namespace prefixes shown in the table are conventional, not mandatory. As is always the case when you declare an XML namespace, you can specify any prefix in your Facelets page. For example, you can declare the prefix for the composite component tag library as

xmlns:composite="jakarta.faces.composite"

instead of as

xmlns:cc="jakarta.faces.composite"

Based on the Jakarta Faces support for Expression Language (EL) syntax, Facelets uses EL expressions to reference properties and methods of managed beans. EL expressions can be used to bind component objects or values to methods or properties of managed beans that are used as backing beans. For more information on using EL expressions, see Using the EL to Reference Managed Beans.

The Lifecycle of a Facelets Application

The Jakarta Faces specification defines the lifecycle of a Jakarta Faces application. For more information on this lifecycle, see The Lifecycle of a Jakarta Faces Application. The following steps describe that process as applied to a Facelets-based application.

  1. When a client, such as a browser, makes a new request to a page that is created using Facelets, a new component tree or jakarta.faces.component.UIViewRoot is created and placed in the FacesContext.

  2. The UIViewRoot is applied to the Facelets, and the view is populated with components for rendering.

  3. The newly built view is rendered back as a response to the client.

  4. On rendering, the state of this view is stored for the next request. The state of input components and form data is stored.

  5. The client may interact with the view and request another view or change from the Jakarta Faces application. At this time, the saved view is restored from the stored state.

  6. The restored view is once again passed through the Jakarta Faces lifecycle, which eventually will either generate a new view or re-render the current view if there were no validation problems and no action was triggered.

  7. If the same view is requested, the stored view is rendered once again.

  8. If a new view is requested, then the process described in Step 2 is continued.

  9. The new view is then rendered back as a response to the client.

Developing a Simple Facelets Application: The guessnumber-faces Example Application

This section describes the general steps involved in developing a Jakarta Faces application. The following tasks are usually required:

  • Developing the managed beans

  • Creating the pages using the component tags

  • Defining page navigation

  • Mapping the FacesServlet instance

  • Adding managed bean declarations

Creating a Facelets Application

The example used in this tutorial is the guessnumber-faces application. The application presents you with a page that asks you to guess a number from 0 to 10, validates your input against a random number, and responds with another page that informs you whether you guessed the number correctly or incorrectly.

The source code for this application is in the jakartaee-examples/tutorial/web/faces/guessnumber-faces/ directory.

Developing a Managed Bean

In a typical Jakarta Faces application, each page of the application connects to a managed bean that serves as a backing bean. The backing bean defines the methods and properties that are associated with the components. In this example, both pages use the same backing bean.

The following managed bean class, UserNumberBean.java, generates a random number from 0 to 10 inclusive:

package ee.jakarta.tutorial.guessnumber;

import java.io.Serializable;
import java.util.Random;

import jakarta.annotation.PostConstruct;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;

@Named
@ViewScoped
public class UserNumberBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private static final int MINIMUM = 0;
    private static final int MAXIMUM = 10;

    private int randomInt;
    private Integer userNumber;
    private String response;

    @PostConstruct
    public void init() {
        randomInt = new Random().nextInt(maximum + 1);
        // Print number to server log.
        System.out.println("Duke's number: " + randomInt);
    }

    public void guess() {
        if (userNumber.compareTo(randomInt) != 0) {
            response = "Sorry, " + userNumber + " is incorrect.";
        }
        else {
            response = "Yay! You got it!";
        }
    }

    public Integer getUserNumber() {
        return userNumber;
    }

    public void setUserNumber(Integer userNumber) {
        this.userNumber = userNumber;
    }

    public String getResponse() {
        return response;
    }

    public int getMinimum() {
        return MINIMUM;
    }

    public int getMaximum() {
        return MAXIMUM;
    }
}

Note the use of the @Named annotation, which makes the managed bean accessible through the EL. The @ViewScoped annotation registers the bean scope as view to enable you to reuse the same bean instance as long as you interact with the same web page without navigating away.

Creating Facelets Views

To create a page or view, you add components to the pages, wire the components to backing bean values and properties, and register converters, validators, or listeners on the components.

For the example application, XHTML web pages serve as the front end. The page of the example application is a page called greeting.xhtml. A closer look at various sections of this web page provides more information.

The first section of the web page declares the document type of the generated HTML output, which is HTML5:

<!DOCTYPE html>

The next section specifies the language of the text embedded in the generated HTML output and then declares the XML namespace for the tag libraries that are used in the web page:

<html lang="en"
      xmlns:h="jakarta.faces.html"
      xmlns:f="jakarta.faces.core">

The next section uses various tags to insert components into the web page:

    <h:head>
        <title>Guess Number Facelets Application</title>
        <h:outputStylesheet name="css/default.css"/>
    </h:head>
    <h:body>
        <h:form>
            <h:graphicImage name="images/wave.svg"
                            alt="Duke waving his hand"
                            width="100" height="100" />
            <h1>
                Hi, my name is Duke. I am thinking of a number from
                #{userNumberBean.minimum} to #{userNumberBean.maximum}.
                Can you guess it?
            </h1>
            <div class="input">
                <h:outputLabel id="userNumberLabel" for="userNumber"
                               value="Enter a number from 0 to 10:" />
                <h:inputText id="userNumber" required="true"
                             value="#{userNumberBean.userNumber}">
                    <f:validateLongRange minimum="#{userNumberBean.minimum}"
                                         maximum="#{userNumberBean.maximum}" />
                </h:inputText>
                <h:message id="userNumberMessage" for="userNumber" />
            </div>
            <div class="actions">
                <h:commandButton id="guess" value="Guess"
                                 action="#{userNumberBean.guess}">
                    <f:ajax execute="@form"
                            render="userNumberMessage response" />
                </h:commandButton>
            </div>
            <div class="output">
                <h:outputText id="response" value="#{userNumberBean.response}" />
            </div>
        </h:form>
    </h:body>

Note the use of the following tags:

  • Facelets HTML tags (those beginning with h:) to add components

  • The Facelets core tag f:validateLongRange to validate the user input

An h:inputText tag accepts user input and sets the value of the managed bean property userNumber through the EL expression #{userNumberBean.userNumber}. The input value is validated for value range by the Jakarta Faces standard validator tag f:validateLongRange.

The image file, wave.svg, is added to the page as a resource, as is the style sheet. For more details about the resources facility, see Web Resources.

An h:commandButton tag with the ID guess starts validation of the input data when a user clicks the button. Using f:ajax, the tag updates the h:message associated with the h:inputText so that it can display any validation error messages. Also the h:outputText is being updated which shows the response to your input.

Configuring the Application

Configuring a Jakarta Faces application involves mapping the Faces Servlet in the web deployment descriptor file, such as a web.xml file, and possibly adding managed bean declarations, navigation rules, and resource bundle declarations to the application configuration resource file, faces-config.xml.

If you are using NetBeans IDE, a web deployment descriptor file is automatically created for you. In such an IDE-created web.xml file, change the default greeting page, which is index.xhtml, to greeting.xhtml. Here is an example web.xml file, showing this change in bold.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
         version="6.0">
    <context-param>
        <param-name>jakarta.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>jakarta.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>greeting.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

Note the use of the context parameter PROJECT_STAGE. This parameter identifies the status of a Jakarta Faces application in the software lifecycle.

The stage of an application can affect the behavior of the application. For example, if the project stage is defined as Development, debugging information is automatically generated for the user. If not defined by the user, the default project stage is Production.

Running the guessnumber-faces Facelets Example

You can use either NetBeans IDE or Maven to build, package, deploy, and run the guessnumber-faces example.

To Build, Package, and Deploy the guessnumber-faces Example Using NetBeans IDE

  1. Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).

  2. From the File menu, choose Open Project.

  3. In the Open Project dialog box, navigate to:

    jakartaee-examples/tutorial/web/faces
  4. Select the guessnumber-faces folder.

  5. Click Open Project.

  6. In the Projects tab, right-click the guessnumber-faces project and select Build.

    This option builds the example application and deploys it to your GlassFish Server instance.

To Build, Package, and Deploy the guessnumber-faces Example Using Maven

  1. Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).

  2. In a terminal window, go to:

    jakartaee-examples/tutorial/web/faces/guessnumber-faces/
  3. Enter the following command:

    mvn install

    This command builds and packages the application into a WAR file, guessnumber-faces.war, that is located in the target directory. It then deploys it to the server.

To Run the guessnumber-faces Example

  1. Open a web browser.

  2. Enter the following URL in your web browser:

    http://localhost:8080/guessnumber-faces
  3. In the field, enter a number from 0 to 10 and click Submit.

    Another page appears, reporting whether your guess is correct or incorrect.

  4. If you guessed incorrectly, click Back to return to the main page.

    You can continue to guess until you get the correct answer, or you can look in the server log, where the UserNumberBean constructor displays the correct answer.

Using Facelets Templates

Jakarta Faces technology provides the tools to implement user interfaces that are easy to extend and reuse. Templating is a useful Facelets feature that allows you to create a page that will act as the base, or template, for the other pages in an application. By using templates, you can reuse code and avoid recreating similarly constructed pages. Templating also helps in maintaining a standard look and feel in an application with a large number of pages.

Facelets Templating Tags lists Facelets tags that are used for templating and their respective functionality.

Facelets Templating Tags
Tag Function

ui:component

Defines a component that is created and added to the component tree.

ui:composition

Defines a page composition that optionally uses a template. Content outside of this tag is ignored.

ui:debug

Defines a debug component that is created and added to the component tree.

ui:decorate

Similar to the composition tag but does not disregard content outside this tag.

ui:define

Defines content that is inserted into a page by a template.

ui:fragment

Similar to the component tag but does not disregard content outside this tag.

ui:include

Encapsulates and reuses content for multiple pages.

ui:insert

Inserts content into a template.

ui:param

Used to pass parameters to an included file.

ui:repeat

Used as an alternative for loop tags, such as c:forEach or h:dataTable.

ui:remove

Removes content from a page.

For more information on Facelets templating tags, see the Jakarta Faces Facelets Tag Library documentation.

The Facelets tag library includes the main templating tag ui:insert. A template page that is created with this tag allows you to define a default structure for a page. A template page is used as a template for other pages, usually referred to as client pages.

Here is an example of a template saved as /WEB-INF/templates/template.xhtml:

<!DOCTYPE html>
<html xmlns:ui="jakarta.faces.facelets"
      xmlns:h="jakarta.faces.html">

    <h:head>
        <title>Facelets Template</title>
        <h:outputStylesheet name="css/default.css"/>
        <h:outputStylesheet name="css/layout.css"/>
    </h:head>

    <h:body>
        <div id="top">
            <ui:insert name="top">Top Section</ui:insert>
        </div>
        <div>
            <div id="left">
                 <ui:insert name="left">Left Section</ui:insert>
            </div>
            <div id="content">
                 <ui:insert name="content">Main Content</ui:insert>
            </div>
        </div>
    </h:body>
</html>

The example page defines an XHTML page that is divided into three sections: a top section, a left section, and a main section. The sections have style sheets associated with them. The same structure can be reused for the other pages of the application.

The client page invokes the template by using the ui:composition tag. In the following example, a client page named templateclient.xhtml invokes the template page named template.xhtml from the preceding example. A client page allows content to be inserted with the help of the ui:define tag.

<ui:composition template="/WEB-INF/templates/template.xhtml">
                xmlns:ui="jakarta.faces.facelets"
                xmlns:h="jakarta.faces.html">
    <ui:define name="top">
        <h1>Welcome to Template Client Page</h1>
    </ui:define>

    <ui:define name="left">
        <p>You are in the Left Section.</p>
    </ui:define>

    <ui:define name="content">
        <header>
            <h:graphicImage name="images/wave.svg"
                            alt="Duke waving his hand"
                            width="100" height="100" />
        </header>
        <p>You are in the Main Content Section.</p>
    </ui:define>
</ui:composition>

You can use NetBeans IDE to create Facelets template and client pages. For more information on creating these pages, see https://netbeans.org/kb/docs/web/jsf20-intro.html.

Composite Components

Jakarta Faces technology offers the concept of composite components with Facelets. A composite component is a special type of template that acts as a component.

Any component is essentially a piece of reusable code that behaves in a particular way. For example, an input component accepts user input. A component can also have validators, converters, and listeners attached to it to perform certain defined actions.

A composite component consists of a collection of markup tags and other existing components. This reusable, user-created component has a customized, defined functionality and can have validators, converters, and listeners attached to it like any other component.

With Facelets, any XHTML page that contains markup tags and other components can be converted into a composite component. Using the resources facility, the composite component can be stored in a library that is available to the application from the defined resources location.

Composite Component Tags lists the most commonly used composite tags and their functions.

Composite Component Tags
Tag Function

composite:interface

Declares the usage contract for a composite component. The composite component can be used as a single component whose feature set is the union of the features declared in the usage contract.

composite:implementation

Defines the implementation of the composite component. If a composite:interface element appears, there must be a corresponding composite:implementation.

composite:attribute

Declares an attribute that may be given to an instance of the composite component in which this tag is declared.

composite:insertChildren

Any child components or template text within the composite component tag in the using page will be reparented into the composite component at the point indicated by this tag’s placement within the composite:implementation section.

composite:valueHolder

Declares that the composite component whose contract is declared by the composite:interface in which this element is nested exposes an implementation of ValueHolder suitable for use as the target of attached objects in the using page.

composite:editableValueHolder

Declares that the composite component whose contract is declared by the composite:interface in which this element is nested exposes an implementation of EditableValueHolder suitable for use as the target of attached objects in the using page.

composite:actionSource

Declares that the composite component whose contract is declared by the composite:interface in which this element is nested exposes an implementation of ActionSource2 suitable for use as the target of attached objects in the using page.

For more information and a complete list of Facelets composite tags, see the Jakarta Faces Facelets Tag Library documentation.

The following example shows a composite component that renders an form field with a label, input and message component:

<ui:component xmlns:ui="jakarta.faces.facelets"
              xmlns:cc="jakarta.faces.composite"
              xmlns:h="jakarta.faces.html">
    <cc:interface>
        <cc:attribute name="label" required="true" />
        <cc:attribute name="value" required="true" />
    </cc:interface>

    <cc:implementation>
        <div id="#{cc.clientId}" class="field">
            <h:outputLabel for="input" value="#{cc.attrs.label}" />
            <h:inputText id="input" value="#{cc.attrs.value}" />
            <h:message for="input" />
        </div>
    </cc:implementation>
</ui:component>

Note the use of cc.attrs.value when defining the value of the outputLabel and inputText components. The word cc in Jakarta Faces is a reserved word for composite components. The #{cc.attrs.attribute-name} expression is used to access the attributes defined for the composite component’s interface, which in this case happens to be value.

The preceding example content is stored as a file named field.xhtml in a folder named resources/mycomponents, under the application web root directory. This directory is considered a library by Jakarta Faces, and a component can be accessed from such a library. The mycomponents folder name is free to your choice. For more information on resources, see Web Resources.

The web page that uses this composite component is generally called a using page. The using page includes a reference to the composite component, in the xml namespace declarations:

<!DOCTYPE html>
<html xmlns:h="jakarta.faces.html"
      xmlns:my="jakarta.faces.composite/mycomponents">

    <h:head>
        <title>Using a sample composite component</title>
    </h:head>

    <h:body>
        <h:form>
            <my:field id="email"
                      label="Enter your email address"
                      value="#{bean.email}" />
        </h:form>
    </h:body>
</html>

The local composite component library is defined in the xmlns namespace with the declaration xmlns:my="jakarta.faces.composite/mycomponents". The my XML namespace are free to your choice. The /mycomponents part must represent the folder name where the composite component files are located. The component itself is accessed through the my:field tag. The preceding example content can be stored as a web page named userpage.xhtml under the web root directory. When compiled and deployed on a server, it can be accessed with the following URL:

http://localhost:8080/application-name/userpage.xhtml

See Composite Components: Advanced Topics and an Example for more information and an example.

Web Resources

Web resources are any software artifacts that the web application requires for proper rendering, including images, script files, and any user-created component libraries. Resources must be collected in a standard location, which can be one of the following.

  • A resource packaged in the web application root must be in a subdirectory of a resources directory at the web application root: resources/resource-identifier.

  • A resource packaged in the web application’s classpath must be in a subdirectory of the META-INF/resources directory within a web application: META-INF/resources/resource-identifier. You can use this file structure to package resources in a JAR file bundled in the web application.

The Jakarta Faces runtime will look for the resources in the preceding listed locations, in that order.

Resource identifiers are unique strings that conform to the following format (all on one line):

[locale-prefix/][library-name/][library-version/]resource-name[/resource-version]

Elements of the resource identifier in brackets ([]) are optional, indicating that only a resource-name, which is usually a file name, is a required element. For example, the most common way to specify a style sheet, image, or script is to use the library and name attributes, as in the following tag from the guessnumber-faces example:s

<h:outputStylesheet library="css" name="default.css"/>

This tag specifies that the default.css style sheet is in the directory web/resources/css.

You can also specify the location of an image using the following syntax, also from the guessnumber-faces example:

<h:graphicImage value="#{resource['images:wave.med.gif']}"/>

This tag specifies that the image named wave.med.gif is in the directory web/resources/images.

Resources can be considered as a library location. Any artifact, such as a composite component or a template that is stored in the resources directory, becomes accessible to the other application components, which can use it to create a resource instance.

Relocatable Resources

You can place a resource tag in one part of a page and specify that it be rendered in another part of the page. To do this, you use the target attribute of a tag that specifies a resource. Acceptable values for this attribute are as follows.

  • “head” renders the resource in the head element.

  • “body” renders the resource in the body element.

  • “form” renders the resource in the form element.

For example, the following h:outputScript tag is placed within an h:form element, but it renders the JavaScript in the head element:

<h:form>
    <h:outputScript name="myscript.js" library="mylibrary" target="head"/>
</h:form>

The h:outputStylesheet tag also supports resource relocation, in a similar way.

Relocatable resources are essential for composite components that use stylesheets and can also be useful for composite components that use JavaScript. See The compositecomponentexample Example Application for an example.

Resource Library Contracts

Resource library contracts allow you to define a different look and feel for different parts of one or more applications, instead of either having to use the same look and feel for all or having to specify a different look on a page-by-page basis.

To do this, you create a contracts section of your web application. Within the contracts section, you can specify any number of named areas, each of which is called a contract. Within each contract you can specify resources such as template files, stylesheets, JavaScript files, and images.

For example, you could specify two contracts named c1 and c2, each of which uses a template and other files:

src/main/webapp
    WEB-INF/
    contracts
        c1
            template.xhtml
            style.css
            myImg.gif
            myJS.js
        c2
            template.xhtml
            style2.css
            img2.gif
            JS2.js
    index.xhtml
    ...

One part of the application can use c1, while another can use c2.

Another way to use contracts is to specify a single contract that contains multiple templates:

src/main/webapp
    contracts
        myContract
            template1.xhtml
            template2.xhtml
            style.css
            img.png
            img2.png

You can package a resource library contract in a JAR file for reuse in different applications. If you do so, the contracts must be located under META-INF/contracts. You can then place the JAR file in the WEB-INF/lib directory of an application. This means that the application would be organized as follows:

src/main/webapp/
    WEB-INF/lib/myContract.jar
    ...

You can specify the contract usage within an application’s faces-config.xml file, under the resource-library-contracts element. You need to use this element only if your application uses more than one contract, however.

The hello1-rlc Example Application

The hello1-rlc example modifies the simple hello1 example from A Web Module That Uses Jakarta Faces Technology: The hello1 Example to use two resource library contracts. Each of the two pages in the application uses a different contract.

The managed bean for hello1-rlc, Hello.java, is identical to the one for hello1 (except that it replaces the @Named and @RequestScoped annotations with @Model).

The source code for this application is in the jakartaee-examples/tutorial/web/faces/hello1-rlc/ directory.

Configuring the hello1-rlc Example

The faces-config.xml file for the hello1-rlc example contains the following elements:

<resource-library-contracts>
    <contract-mapping>
        <url-pattern>/reply/*</url-pattern>
        <contracts>reply</contracts>
    </contract-mapping>
    <contract-mapping>
        <url-pattern>*</url-pattern>
        <contracts>hello</contracts>
    </contract-mapping>
</resource-library-contracts>

The contract-mapping elements within the resource-library-contracts element map each contract to a different set of pages within the application. One contract, named reply, is used for all pages under the reply area of the application (/reply/*). The other contract, hello, is used for all other pages in the application (*).

The application is organized as follows:

hello1-rlc
    pom.xml
    src/main/java/jakarta/tutorial/hello1rlc/Hello.java
    src/main/webapp
        WEB-INF
            faces-config.xml
            web.xml
        contracts
            hello
                default.css
                duke.handsOnHips.gif
                template.xhtml
            reply
                default.css
                duke.thumbsup.gif
                template.xhtml
        reply
            response.xhtml
        greeting.xhtml

The web.xml file specifies the welcome-file as greeting.xhtml. Because it is not located under src/main/webapp/reply, this Facelets page uses the hello contract, whereas src/main/webapp/reply/response.xhtml uses the reply contract.

The Facelets Pages for the hello1-rlc Example

The greeting.xhtml and response.xhtml pages have identical code calling in their templates:

<ui:composition template="/template.xhtml">

The template.xhtml files in the hello and reply contracts differ only in two respects: the placeholder text for the title element ("Hello Template" and "Reply Template") and the graphic that each specifies.

The default.css stylesheets in the two contracts differ in only one respect: the background color specified for the body element.

To Build, Package, and Deploy the hello1-rlc Example Using NetBeans IDE

  1. Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).

  2. From the File menu, choose Open Project.

  3. In the Open Project dialog box, navigate to:

    jakartaee-examples/tutorial/web/faces
  4. Select the hello1-rlc folder.

  5. Click Open Project.

  6. In the Projects tab, right-click the hello1-rlc project and select Build.

    This option builds the example application and deploys it to your GlassFish Server instance.

To Build, Package, and Deploy the hello1-rlc Example Using Maven

  1. Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).

  2. In a terminal window, go to:

    jakartaee-examples/tutorial/web/faces/hello1-rlc/
  3. Enter the following command:

    mvn install

    This command builds and packages the application into a WAR file, hello1-rlc.war, that is located in the target directory. It then deploys it to your GlassFish Server instance.

To Run the hello1-rlc Example

  1. Enter the following URL in your web browser:

    http://localhost:8080/hello1-rlc
  2. The greeting.xhtml page looks just like the one from hello1 except for its background color and graphic.

  3. In the text field, enter your name and click Submit.

  4. The response page also looks just like the one from hello1 except for its background color and graphic.

    The page displays the name you submitted. Click Back to return to the greeting.xhtml page.

HTML5-Friendly Markup

When you want to produce user interface features for which HTML does not have its own elements, you can create a custom Jakarta Faces component and insert it in your Facelets page. This mechanism can cause a simple element to create complex web code. However, creating such a component is a significant task (see Creating Custom UI Components and Other Custom Objects).

HTML5 offers new elements and attributes that can make it unnecessary to write your own components. It also provides many new capabilities for existing components. Jakarta Faces technology supports HTML5 not by introducing new UI components that imitate HTML5 ones but by allowing you to use HTML5 markup directly. It also allows you to use Jakarta Faces attributes within HTML5 elements. Jakarta Faces technology support for HTML5 falls into two categories:

  • Pass-through elements

  • Pass-through attributes

The effect of the HTML5-friendly markup feature is to offer the Facelets page author almost complete control over the rendered page output, rather than having to pass this control off to component authors. You can mix and match Jakarta Faces and HTML5 components and elements as you see fit.

Using Pass-Through Elements

Pass-through elements allow you to use HTML5 tags and attributes but to treat them as equivalent to Jakarta Faces components associated with a server-side UIComponent instance.

To make an element that is not a Jakarta Faces element a pass-through element, specify at least one of its attributes using the jakarta.faces namespace. For example, the following code declares the namespace with the short name faces:

<html ... xmlns:faces="jakarta.faces"
...
    <input type="email" faces:id="email" name="email"
           value="#{reservationBean.email}" required="required"/>

Here, the faces prefix is placed on the id attribute so that the HTML5 input tag’s attributes are treated as part of the Facelets page. This means that, for example, you can use EL expressions to retrieve managed bean properties.

How Facelets Renders HTML5 Elements shows how pass-through elements are rendered as Facelets tags. The faces implementation uses the element name and the identifying attribute to determine the corresponding Facelets tag that will be used in the server-side processing. The browser, however, interprets the markup that the page author has written.

How Facelets Renders HTML5 Elements
HTML5 Element Name Identifying Attribute Facelets Tag

a

faces:action

h:commandLink

a

faces:actionListener

h:commandLink

a

faces:value

h:outputLink

a

faces:outcome

h:link

body

h:body

button

h:commandButton

button

faces:outcome

h:button

form

h:form

head

h:head

img

h:graphicImage

input

type="button"

h:commandButton

input

type="checkbox"

h:selectBooleanCheckbox

input

type="color"

h:inputText

input

type="date"

h:inputText

input

type="datetime"

h:inputText

input

type="datetime-local"

h:inputText

input

type="email"

h:inputText

input

type="month"

h:inputText

input

type="number"

h:inputText

input

type="range"

h:inputText

input

type="search"

h:inputText

input

type="time"

h:inputText

input

type="url"

h:inputText

input

type="week"

h:inputText

input

type="file"

h:inputFile

input

type="hidden"

h:inputHidden

input

type="password"

h:inputSecret

input

type="reset"

h:commandButton

input

type="submit"

h:commandButton

input

type="*"

h:inputText

label

h:outputLabel

link

h:outputStylesheet

script

h:outputScript

select

multiple="*"

h:selectManyListbox

select

h:selectOneListbox

textarea

h:inputTextArea

Using Pass-Through Attributes

Pass-through attributes are the converse of pass-through elements. They allow you to pass attributes that are not Jakarta Faces attributes through to the browser without interpretation. If you specify a pass-through attribute in a Jakarta Faces UIComponent, the attribute name and value are passed straight through to the browser without being interpreted by Jakarta Faces components or renderers. There are several ways to specify pass-through attributes.

  • Use the Jakarta Faces namespace for pass-through attributes to prefix the attribute names within a Jakarta Faces component. For example, the following code declares the namespace with the short name p, then passes the type, min, max, required, and title attributes through to the HTML5 input component:

    <html ... xmlns:p="jakarta.faces.passthrough"
    ...
    
    <h:form prependId="false">
    <h:inputText id="nights" p:type="number" value="#{bean.nights}"
                 p:min="1" p:max="30" p:required="required"
                 p:title="Enter a number between 1 and 30 inclusive.">
            ...

    This will cause the following markup to be rendered (assuming that bean.nights has a default value set to 1):

    <input id="nights" type="number" value="1" min="1" max="30"
           required="required"
           title="Enter a number between 1 and 30 inclusive.">
  • To pass a single attribute, nest the f:passThroughAttribute tag within a component tag. For example:

    <h:inputText value="#{user.email}">
        <f:passThroughAttribute name="type" value="email" />
    </h:inputText>

    This code would be rendered similarly to the following:

    <input value="me@me.com" type="email" />
  • To pass a group of attributes, nest the f:passThroughAttributes tag within a component tag, specifying an EL value that must evaluate to a Map<String, Object>. For example:

    <h:inputText value="#{bean.nights}">
        <f:passThroughAttributes value="#{bean.nameValuePairs}" />
    </h:inputText>

    If the bean used the following Map declaration and initialized the map in the constructor as follows, the markup would be similar to the output of the code that uses the pass-through attribute namespace:

    private Map<String, Object> nameValuePairs;
    ...
    public Bean() {
        this.nameValuePairs = new HashMap<>();
        this.nameValuePairs.put("type", "number");
        this.nameValuePairs.put("min", "1");
        this.nameValuePairs.put("max", "30");
        this.nameValuePairs.put("required", "required");
        this.nameValuePairs.put("title",
                "Enter a number between 1 and 4 inclusive.");
    }

The reservation Example Application

The reservation example application provides a set of HTML5 input elements of various types to simulate purchasing tickets for a theatrical event. It consists of two Facelets pages, reservation.xhtml and confirmation.xhtml, and a backing bean, ReservationBean.java. The pages use both pass-through attributes and pass-through elements.

The source code for this application is in the jakartaee-examples/tutorial/web/faces/reservation/ directory.

The Facelets Pages for the reservation Application

The first important feature of the Facelets pages for the reservation application is the DOCTYPE header. The facelets pages for this application begin simply with the following DOCTYPE header, which indicates that the XHTML-generated result is an HTML5 page:

<!DOCTYPE html>

The namespace declarations in the html element of the reservation.xhtml page specify both the faces and the passthrough namespaces:

<html lang="en"
      xmlns:faces="jakarta.faces"
      xmlns:f="jakarta.faces.core"
      xmlns:h="jakarta.faces.html"
      xmlns:p="jakarta.faces.passthrough">

Next, an h:head tag followed by an h:outputStylesheet tag within the h:body tag illustrates the use of a relocatable resource (as described in Relocatable Resources):

<h:head>
    <title>Reservation Application</title>
</h:head>
<h:body>
    <h:outputStylesheet name="css/stylesheet.css" target="head" />

The reservation.xhtml page uses a HTML5-specific input element type on h:inputText, which is date.

    <h:inputText id="date" type="date"
                 value="#{reservationBean.date}" required="true"
                 title="Enter or choose a date." />

The field for the number of tickets uses the f:passThroughAttributes tag to pass a Map defined in the managed bean. It also recalculates the total in response to a change in the field:

    <h:inputText id="tickets" value="#{reservationBean.tickets}">
        <f:passThroughAttributes value="#{reservationBean.ticketAttrs}"/>
        <f:ajax listener="#{reservationBean.calculateTotal}"
                render="total" />
    </h:inputText>

The field for the price specifies the min, max and step as a pass-through attribute of the h:inputText element, offering a range of four ticket prices. Here, the p prefix on the HTML5 attributes passes them through to the browser uninterpreted by the Jakarta Faces input component:

    <h:inputText id="price" type="number"
                 value="#{reservationBean.price}" required="true"
                 p:min="80" p:max="120" p:step="20"
                 title="Enter a price: 80, 100, 120, or 140.">
        <f:ajax listener="#{reservationBean.calculateTotal}"
                render="total" />
    </h:inputText>

The output of the calculateTotal method that is specified as the listener for the Ajax event is rendered in the output element whose id and name value is total. See Using Ajax with Jakarta Faces Technology, for more information.

The second Facelets page, confirmation.xhtml, uses a pass-through output element to display the values entered by the user and provides a Facelets h:commandButton tag to allow the user to return to the reservation.xhtml page.

The Managed Bean for the reservation Application

The session-scoped managed bean for the reservation application, ReservationBean.java, contains properties for all the elements on the Facelets pages. It also contains two methods, calculateTotal and clear, that act as listeners for Ajax events on the reservation.xhtml page.

To Build, Package, and Deploy the reservation Example Using NetBeans IDE

  1. Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).

  2. From the File menu, choose Open Project.

  3. In the Open Project dialog box, navigate to:

    jakartaee-examples/tutorial/web/faces
  4. Select the reservation folder.

  5. Click Open Project.

  6. In the Projects tab, right-click the reservation project and select Build.

    This option builds the example application and deploys it to your GlassFish Server instance.

To Build, Package, and Deploy the reservation Example Using Maven

  1. Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).

  2. In a terminal window, go to:

    jakartaee-examples/tutorial/web/faces/reservation/
  3. Enter the following command:

    mvn install

    This command builds and packages the application into a WAR file, reservation.war, that is located in the target directory. It then deploys the WAR file to your GlassFish Server instance.

To Run the reservation Example

At the time of the publication of this tutorial, the browser that most fully implements HTML5 is Google Chrome, and it is recommended that you use it to run this example. Other browsers are catching up, however, and may work equally well by the time you read this.

  1. Enter the following URL in your web browser:

    http://localhost:8080/reservation
  2. Enter information in the fields of the reservation.xhtml page.

    The Performance Date field has a date field with up and down arrows that allow you to increment and decrement the month, day, and year as well as a larger down arrow that brings up a date editor in calendar form.

    The Number of Tickets and Ticket Price fields also have up and down arrows that allow you to increment and decrement the values within the allowed range and steps. The Estimated Total changes when you change either of these two fields.

    Email addresses and dates are checked for format, but not for validity (you can make a reservation for a past date, for instance).

  3. Click Make Reservation to complete the reservation or Clear to restore the fields to their default values.

  4. If you click Make Reservation, the confirmation.xhtml page appears, displaying the submitted values.

    Click Back to return to the reservation.xhtml page.