JSF 2.0 Test Drive Part 2: Developing a Website with Facelets Templating

As part of my work on JSR 314 (JSF 2.0) I've been reviewing the specification, Javadocs, and tag library docs for accuracy. One way I do this is to make examples that test drive what the documentation says JSF 2.0 will do.

In Part 1 of this series, I showed how to develop an Ajaxified JSF 2.0 Facelet Composite Component.

Now here's Part 2 of my JSF 2.0 Test Drive... Developing a Website with Facelets Templating

Facelets Templating

Templating -- what's that? Well templating refers to a technology that you would use to control the layout and content of a website. It's kind of like Liferay Portal's "Layout Template" feature that lets you control how portlets are arranged on the portal page.

The premiere view-handler in JSF 2.0 is Facelets, which provides a powerful templating engine designed especially for JSF. Websites typically have a layout of sections that is common for all pages: header, navigation, main content, and footer. That's where Facelets Templating comes in to save the day.

Downloadable Source Code

The Maven 2 project source code is licensed under the MPL 1.1 and is available at the edoras framework SVN repo:

http://svn.portletfaces.org/svn/portletfaces/legacy/examples/trunk/webapps/org.edorasframework.example.facelet.template.jsf.2.0/

Home Page Screen Shot

Here is a screen shot of the home page for the website:

The "Welcome Our Company Website" light-gray rectangle at the top is the "header" of the website. This is kind of like a banner that is to appear at the top of every web page in the site. It typically never changes.

The Home, Products, and Contact Us links are part of the "navigation" for the site. The links typically change a little from page to page in a real world site.

The "Welcome to the HOME page" dark-gray rectangle on the right is the "main" content for each page. This is the content in this part typically changes quite a bit for each page.

The "Copyright" light-gray rectangle on the bottom is the "footer" for the website. Like the header, it typically never changes.

Template Source Markup: template.xhtml

Here is the markup for the template. It's basically a Facelets f:view that specifies an h:panelGroup (renders a <div> layer) for the header, and another for the footer. Note that those sections use the Facelets ui:include tag in order to insert the contents of the header and footer info, which lives in separate XHTML files. In the middle is an h:panelGrid, which renders a two-column HTML <table>. Note the Facelets ui:insert tags -- they are kind of like markers that indicate that something will be inserted at runtime. More on that when we look at the ui:define tags in the Home page. Also, note that the Facelets ui:debug tag is specified in the template -- that's kind of a best practice for helping JSF developers debug the server-side state of things.

<f:view 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"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.w3.org/1999/xhtml http://www.w3.org/2002/08/xhtml/xhtml1-transitional.xsd">

  <!-- Enables CTRL+SHIFT+D for activating Facelets debug window -->
  <ui:debug />

  <html>
  <h:head>
    <ui:insert name="htmlHead" />
    <link rel="stylesheet" type="text/css" href="css/template.css" />
  </h:head>
  <h:body>
    <h:panelGroup layout="block" styleClass="header">
      <ui:include src="/WEB-INF/includes/header.xhtml" />
    </h:panelGroup>
    <h:panelGrid columns="2" columnClasses="nav-col, main-col" styleClass="middle-table">
      <h:panelGroup layout="block">
        <h:form>
          <ui:insert name="navigation" />
        </h:form>
      </h:panelGroup>
      <h:panelGroup layout="block">
        <ui:insert name="main" />
      </h:panelGroup>
    </h:panelGrid>
    <h:panelGroup layout="block" styleClass="footer">
      <ui:include src="/WEB-INF/includes/footer.xhtml" />
    </h:panelGroup>
  </h:body>
  </html>
</f:view>

Home Page Source Markup: home.xhtml

Here's the markup for the home page. Note that it's not a Facelets f:view at all -- instead its a ui:composition that specifies template.xhtml as the Facelet template to be used for rendering. The main thing to point out here is that the ui:define tag "defines" the content that is to be inserted into the template via the corresponding ui:insert tag found in the template.

<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.w3.org/1999/xhtml http://www.w3.org/2002/08/xhtml/xhtml1-transitional.xsd"
  template="/WEB-INF/includes/template.xhtml">

  <ui:define name="htmlHead">
    <meta name="description" content="Our Company Home Page" />
    <title>Our Company - Home</title>
  </ui:define>

  <ui:define name="navigation">
    <h:outputText styleClass="selected" value="Home" />
    <h:commandLink action="products" value="Products" />
    <h:commandLink action="contact-us" value="Contact Us" />
  </ui:define>

  <ui:define name="main">
    <h:outputText value="Welcome to the HOME page." />
  </ui:define>

</ui:composition>

The remainer of the files (header, footer, products page, contact-us page) are the SVN repos.

Again, hope you enjoyed seeing JSF 2.0 in action! Good stuff ahead!