JSF Facelets Template Project

Russell Bateman
1 March 2011
last update:

Table of Contents

Preface and prerequisites
The presentation (xHTML) files
Application launch
Rendering HTML constructs in xHTML
Appendix: Links and to-dos
Appendix: Finished files

Preface and prerequisites

This is a tutorial for a JavaServerFaces Facelets project that uses templating and is an extension of the research I did in a previous article, Simple JSF Facelets Project. If there are any prerequisites to reading this article, they would be summed up on that one for I'm not going to revisit setting up a project, choosing and setting up JARs or any of the other basic things already well covered there. See the Eclipse project contents by clicking on the image at the right.

The presentation (xHTML) files

This is the bit in this tutorial that you've come to learn because nothing else is really different from the simple Facelets example I wrote about in my previous article. We're actually demonstrating two new things here, inclusion and templating. Do not mix the two up. The first is, in our case here, in service of the second, but it's not, formall speaking, part of templating.

Inclusion makes use of the <ui:include ... /> tag. Where it occurs, you get the contents of the file named by the src attribute inserted into the page being rendered in the location of the ui:include directive.

The header and footer files in our example are being rendered to the final page by inclusion and not by templating although they are included by the template for rendering into the consuming file.

Templating boils down to the use of two files (or sets of files):

I prefer to use the term "consumer" to refer to the second file. In one article I read on this topic, the author had actually reversed the nomenclature which was very misleading.

Template file

For clarity's sake, the template and supporting files, header.xhtml and footer.xhtml, are kept in a subdirectory, templates.

The header, footer and content for the ultimate, rendered page are united by the template file, which is then consumed by the client or consumer file, home.html.

The entire content region of the displayed page is controlled by this template file which is why we titled this file, content.xhtml. In this example the side menu is considered part of the content. Whether it is or should be is debatable, of course. To simplify the example, which is based on several tutorials I read, I decided to leave it part thereof, which is not something I would tend to do in my own work.

How this works...

Remember: the files header.xhtml and footer.xhtml are not anything to do with templating, but with mere inclusion. The template file happens to include them.

content.xhtml, the template file, acts with the final, consuming file, home.xhtml, to accomplish the templating in our example.

It is the consuming file that the browser/client asks to be rendered. The user doesn't really see the template and other, contributing files.

Application launch

To launch the guess-a-number web application, pop open a browser and type:

http://localhost:9080/JsfFacelets-templating/faces/home.xhtml

or, if you haven't had to change Tomcat's standard port, http://localhost:8080/JsfFacelets-templating/faces/home.xhtml

Rendering HTML contructs like &nbsp;, &copy;, &mdash;, etc.

A word about some HTML you're used to writing: You have to use

& # code ;

...as xHTML is the culprit that ignores them, where "code" is, e.g.: 169 in the case of the copyright symbol. For a list of some of these, see http://htmlhelp.com/reference/charset/iso160-191.html. This is relevant to (and demonstrated in) footer.xhtml below.

Appendix: Finished files

WebContent/templates/header.xhtml:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!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">
<body>
<!-- This file is merely included by content.xhml. -->
<div id="header">
	<span class="indent">Basic, Facelets Template Example</span>
</div>
</body>
</html>
WebContent/templates/footer.xhtml:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!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">
<body>
<!-- This file is merely included by content.xhml. -->
<div id="footer">
	<span class="indent">Copyright &#169; 2011 by Etretat Logiciels, LLC</span>
</div>
</body>
</html>
WebContent/templates/content.xhtml:
<!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:h="http://java.sun.com/jsf/html">
<head>
	<link rel="stylesheet" type="text/css" href="#{resource['css:styles.css']}" />
	<title>
		<ui:insert name="title">Facelets Templating Example</ui:insert>
	</title>
</head>
<body>
<!-- All (header, footer and content) are united here by this file, which is
	summarily included in home.html. See home.xhtml, indeed, see what is
	displayed in the rendered page, for the full explanation.
  -->
<div id="header">
  <ui:insert name="header">
    <ui:include src="header.xhtml"/>
  </ui:insert>
</div>

<table width="100%">
<tr>
  <td class="sidemenu" width="20%">
	<!-- This demonstrates that the entire content region of the displayed
		page is controlled in this file which is why we titled this file,
		"content.xhtml." In this example the side menu is considered part
		of the content. Whether it is or should be is debatable, of course.
	  -->
    <div id="sidemenu">
      <br />
      <ui:insert name="sidemenu">
        <h:form>
          <h:commandLink value="Home"></h:commandLink>
          <br />
          <br />
          <h:commandLink value="News"></h:commandLink>
          <br />
          <br />
          <h:commandLink value="Articles"></h:commandLink>
          <br />
          <br />
          <h:commandLink value="About Us"></h:commandLink>
          <br />
          <br />
        </h:form>
      </ui:insert>
    </div>
  </td>
  <td width="85%">
    <ui:insert name="content">
      Content displayed from Template... This text is never
      included, but only the text enclosed in the "ui:define"
      element of the template client or consumer (in this case
      home.xhtml).
    </ui:insert>
  </td>
</tr>
</table>

<div id="footer">
  <ui:insert name="footer">
    <ui:include src="footer.xhtml"/>
  </ui:insert>
</div>
</body>
</html>
WebContent/home.xhtml:
<!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:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">

<!-- See content.xhtml for an explanation of how templating works in this application.
	According to some explanations, this is the "template client." A better name might
	be "consumer."
  -->
  <ui:composition template="/templates/content.xhtml">
    <ui:define name="content">
      <div class="indent">
      <h4> Welcome </h4>
      <p>
      This is an example of a simple Facelets template. Here, header, footer and
      side menu bar appear from the template file (<i>content.xhtml</i>). This
      section (rendering here--what you're reading) appears from the
      template client (<i>home.xhtml</i>).
      </p>

      <p>
      All (header, footer and content) are united in the template file,
      <i>content.xhtml</i>, which is summarily included by this file
      (<i>home.html</i>).
      </p>

      <h4> How this works... </h4>

      <p>
      The files <i>header.xhtml</i> and <i>footer.xhtml</i> are NOT anything to
      do with templating, but with mere inclusion. The template file happens to
      include them.
      </p>

      <p>
      <i>content.xhtml</i>, the template file, acts with this file
      (<i>home.xhtml</i>), also formally known as the template client or
      "consumer," to accomplish the templating in our example.
      </p>

      <p>
      Think of a single page (this example). The template file is the one that
      makes use of <tt><ui:insert ... /></tt> while the template client
      makes use of <tt><ui:define ... /></tt>. <i>home.xhtml</i> and not
      <i>content.xhml</i> is what is "visible" to the browser user (i.e.: is
      on the URI) who does not request the template file (<i>content.xhml</i>),
      <i>header.xhtml</i>, or <i>footer.xhtml</i>, but only this file
      (<i>home.xhtml</i>). That's why all except this file are subsumed under
      the template subdirectory.
      </p>
      </div>
    </ui:define>
  </ui:composition>
</html>
WebContent/resources/css/styles.css:
html { font-family: Candara, Trebuchet MS, Arial, sans-serif; }
body { width: 750px; }
#header
{
	width:				100%;
	font-size:			36px;
	font-weight:		bold;
	line-height:		48px;
	background-color:	navy;
	color:				white;
}
#footer
{
	width:				100%;
	font-weight:		bold;
	background-color:	navy;
	color:				white;
}

.sidemenu
{
	text-align:			center;
	vertical-align:		top;
	background-color:	#E0E0E0;
}


.indent { margin-left: 20px; }
WebContent/WEB-INF/faces-config.xml:
<?xml version="1.0" encoding="UTF-8"?>

<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                   http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
    version="1.2">

<application>
	<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
</application>

</faces-config>
WebContent/WEB-INF/web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns="http://java.sun.com/xml/ns/javaee"
		xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
		xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
						http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
		id="WebApp_ID"
		version="2.5">
  <display-name>JsfFacelets-templating</display-name>
  <filter>
    <display-name>RichFaces Filter</display-name>
    <filter-name>richfaces</filter-name>
    <filter-class>org.ajax4jsf.Filter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>richfaces</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
  </filter-mapping>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>
  <listener>
    <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
  </listener>
  <context-param>
    <param-name>org.richfaces.SKIN</param-name>
    <param-value>blueSky</param-value>
  </context-param>
  <context-param>
    <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
    <param-value>resources.application</param-value>
  </context-param>
  <context-param>
    <description>
		State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2.
		</description>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
  </context-param>
  <context-param>
    <description>
		This parameter tells MyFaces if JavaScript code should be allowed in
		the rendered HTML output.
		If JavaScript is allowed, command_link anchors will have JavaScript code
		that submits the corresponding form.
		If JavaScript is not allowed, the state saving info and nested parameters
		will be added as URL parameters.
		Default is 'true'
		</description>
    <param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name>
    <param-value>true</param-value>
  </context-param>
  <context-param>
    <description>
		If true, rendered HTML code will be formatted, so that it is 'human-readable'
		i.e. additional line separators and whitespace will be written, that do not
		influence the HTML code.
		Default is 'true'
		</description>
    <param-name>org.apache.myfaces.PRETTY_HTML</param-name>
    <param-value>true</param-value>
  </context-param>
  <context-param>
    <param-name>org.apache.myfaces.DETECT_JAVASCRIPT</param-name>
    <param-value>false</param-value>
  </context-param>
  <context-param>
    <description>
		If true, a javascript function will be rendered that is able to restore
		the former vertical scroll on every request. Convenient feature if you
		have pages with long lists and you do not want the browser page to always
		jump to the top if you trigger a link or button action that stays on the
		same page.
		Default is 'false'
		</description>
    <param-name>org.apache.myfaces.AUTO_SCROLL</param-name>
    <param-value>true</param-value>
  </context-param>
  <context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
  </context-param>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>