5 The Templating System

One of the most important functionalities offered by JSF is the templating system. Professional web applications require a uniform appearance, and templates are useful in helping us achieve this, since they allow us to define an application’s basic look and layout. Once this is done, the content areas of different pages can be created on a page-by-page basis.

In light of the above, it’s important you have a clear picture of the templates to be used before you begin designing the actual content. For this reason, we will now spend some time taking a detailed look at JSF’s template technology. We’ll then design templates for (almost) all the pages of our application that are still to be created.

You can continue with the project in your own Codenvy workspace, or you can use the following temporary workspace.

Start Cloud IDE

My-Campaign after Chapter 4 (I18N)


5.1 Templating with Facelets

The basic principle is easily explained. A template is an XHTML document that declares areas with special tags and furnishes them with unique names or place holders. The areas can have default content. Other XHTML documents (template clients) can refer to the template and populate the areas with their own content. Areas are identified by the names specified in the template. The templating system introduces special tags for definining and using templates. The tags belong to the namespace xmlns:ui="http://xmlns.jcp.org/jsf/facelets". The most important tags are listed in the following table, ‎Tab. 5-1.

Facelet Tag Explanation
<ui:insert> This tag can be used in a template to define a placeholder with default content. The tag contains a unique name (attribute name) to enable a template client to refer to it. Example: <ui:insert name="title">   Default Title</ui:insert>
<ui:composition> This tag enables a template to be referenced within a JSF page (template client). The attribute template takes the name of the template file as a value. Everything inside the tags is governed by the templating mechanism.Example:<ui:composition template="template.xhtml"><ui:composition/>
<ui:define> This tag is used within a composition (<ui:composition>) and establishes a reference to a particular content area (<ui:insert>) in the template. The reference is made using the name of the content area. <ui:define> in the composition and <ui:insert> in the template must match in the attribute name. Example:<ui:define name="title">   My Concrete Title</ui:define>
<ui:include> The tag enables JSF pages to be re-used. The attribute src allows the user to specify the files that should be used by the server in place of the tags. Example:<ui:include src="other.xhtml"/>

Tab. 5-1     A very brief overview of the most important tags in the JSF template system

5.2 A Template for My-Campaign

We are going to build a simple template for the web application My-Campaign. The template is a complete XHTML page that establishes a content area (content) inside the HTML body. A template client can then replace the content area at runtime. Alongside the XHTML template, we will also define a CSS (Cascading Style Sheet) to improve the way the page is displayed.

XHTML Template

‎Listing  5-1  shows the template for our web application. It is a complete XTHML page containing both XHTML tags and special JSF tags.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://xmlns.jcp.org/jsf/html"
	xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
	<h:head>
		<title>My-Campaign</title>
		<meta charset="utf-8" />
		<h:outputStylesheet name="/screen.css" />
	</h:head>
	<h:body>
		<div id="container">
			<div id="header">
				<p>Sample Application <b>My-Campaign</b> – Tutorial Java EE 7</p>
			</div>
			<div id="content">
				<ui:insert name="content">
					[Template content will be inserted here]
				</ui:insert>
			</div>
			<div id="footer">
				<p> (C) 2015-2016 Schiesser/Schmollinger, MIT License</p>
			</div>
		</div>
	</h:body>
</html>

Listing 5-1     Facelet template.xhtml

Along with the above-mentioned JSF Facelet template tags, we will also be using JSF HTML tags (namespace http://xmlns.jcp.org/jsf/html). Most of ones we use at this stage will be self-explanatory, (<h:head>, <h:body>) since they have direct equivalents in HTML. The integration of the CSS file will occur via the tag <h:outputStylesheet>, which requests the file name (relative to the project) via the attribute name. We will store our template within the structure of the web project in the directory srcmainwebappWEB-INF.

Cascading Style Sheet (CSS)

In ‎Listing 5-1, the HTML tag <div> is used to define the areas that can be individually formatted using the CSS. We have established the areas container, header, content and footer. The CSS contains format specifications for the HTML standard elements <body> and <h2> as well as for the container, header and footer areas that we introduced ourselves. We can use the CSS to determine which fonts, colours, frames and margins should be used for different areas.

body {
	margin: 0;
	padding: 0;
	background-color: #EAECEE;
	font-family: Verdana, sans-serif;
	font-size: 0.9em;
}
#container {
	margin: 0 auto;
	padding: 0 20px 10px 20px;
	border: 1px solid #666666;
	width: 865px; 
	padding-top: 10px;
}
#header {
	font-size: 1.3em;
	border: 1px solid #666666;
	background: #EAECEE;
	padding: 0 15px 5px 15px;
	margin-bottom: 50px;
}
#footer {
	clear: both;
	text-align: center;
	color: #666666;
	font-size: 0.85em;
	padding: 3em 0 0 0;
}
h2 {
	font-size: 1.2em;
}

Listing 5-2     CSS file screen.css

We will create the directory srcmainwebappresources within the project structure. We will store our CSS file in this directory under the name screen.css (srcmainwebappresourcesscreen.css).

The Template in Use

To put the template into action, we need make further adjustments to our welcome page index.xhtml from as shown in ‎Listing 5-3. Until now, the Facelet has contained the description for a complete page. We use the <ui:composition> tag to reference our template and the <ui:define> tag to set our welcome text as content. The ability to change the title is not provided for within the template, so it is omitted from the welcome page without being replaced.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" 	
	xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
	<body>
		<ui:composition template="WEB-INF/template.xhtml">
		<ui:define name="content">
				<h1>#{msg['welcome.text']}</h1>
			</ui:define>
		</ui:composition>
	</body>
</html>

 Listing 5-3     Facelet index.xhtml 

We can test the page out by rerunning the WildFly runner and opening the browser by clicking on the provided link. The browser should display the page as it appears in Figure 5-1.

The template in use.
Fig. 5-1     The template in use

Mapping a URL to a Facelet

JSF requests are processed on the server using the Faces servlet. We saw that the servlet is activated when the URL ending …/index.jsf is accessed and the JSF processing for the Facelet index.xhtml has begun. The URL endings …/index.faces and …/faces/index.xhtml can also be used as options for activating the servlet.

The first two cases involve extension mapping, while the last one involves prefix mapping. All three variants will work as long as as you have not explicitly set the mapping to the Faces-Servlet via the corresponding configuration in the file src/main/webapp/WEB-INF/web.xml.

5.3 Resource Library Contracts

Attentive readers will no doubt be wondering why we have not localized the template in ‎Listing 5-1. Without doubt, this localization could have been carried out using the method described in the previous chapter without any further adjustments being made. Since JSF 2, it is even possible to localize resources like CSS and graphics files, giving the application the ability to change its appearance depending on the locale. This approach is sufficient in most cases. If, however, you wish to enable the dynamic substitution of one application-specific template and its related resources for another in a whole then a different JSF concept should be used.

A mechanism called Resource Library Contracts (RLC), which was made available for the first time in JSF 2.2, provides a method by which Facelet templates and its related resources (e.g. graphics, CSS or JavaScript files) can be applied to the entire JSF application in the same way as a library and hence can be exchanged easily. The specification refers to the resource collections as contracts for short. The templates and resources are gathered in a directory named contracts. The directory can be directly incorporated into the contracts directory in the root of the WAR file or be inserted in the form of a JAR file in the WEB-INFlib directory of your JSF application.

To enable the Facelets to be able to refer to a contract, the templates contained therein and their insertion points (<ui:insert>) must be known. Supplementary resources may also be known, but are optional. Informally, these three elements form the resource library contract between the user and the contract provider. So long as the contract remains unchanged, alternative contracts can be used without adjusting the Facelets by switching either the contract directory or the JAR file.

Several such contracts can be deposited in each JSF application. By entering URL patterns in the configuration file faces-config.xml, you are able to define which area or view of the application should work with which template. The choice of usable templates can also be controlled dynamically at runtime. This makes it possible for the appearance of a JSF application to be changed in accordance with user input or other environmental data.

Language determines layout and design

The idea is to use RLCs to make the look of an application dependent on the locale of the user. When managing the language dependency of a locale, another set of templates and resources are used. These allow the developer to dynamically adjust the layout and design of the application depending on the language and cultural area in which it is being used and so perhaps to gain a higher level of acceptance among users. In the following section, we will use the locales en and de to show how this can be done.

First, we will create the directory srcmainwebappcontracts. Here, we can store the directories containing the contracts of the application. In our case, we will name the directories after the locales, meaning the names of the directories to be created are srcmainwebappcontractsen and srcmainwebappcontractsde. We will move the file template.xhtml from the folder srcmainwebappWEB-INF and the file screen.css from the folder srcmainresources and deposit them in srcmainwebappcontractsen[1].

It would undoubtedly be possible to find interesting ideas for developing entirely different user interfaces for the English- and German-speaking regions, but that is not the focus of this chapter. For this reason, we’ll keep things simple and deposit a second copy of both these files in the folder srcmainwebappcontractsde. To enable us to tell the difference when using them, however, we’ll need at least to translate the texts in the German template (see‎ Listing 5-4).

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://xmlns.jcp.org/jsf/html"
	xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
	<h:head>
		<title>My-Campaign</title>
		<meta charset="utf-8" />
		<h:outputStylesheet name="/screen.css" />
	</h:head>
	<h:body>
		<div id="container">
			<div id="header">
			<p>Beispielanwendung <b>My-Campaign</b> – Tutorial Java EE 7</p>
			</div>
			<div id="content">
				<ui:insert name="content">
					[Inhalt wird hier eingefügt]
				</ui:insert>
			</div>
			<div id="footer">
				<p> (C) 2015  Schiesser/Schmollinger, MIT license</p>
			</div>
	</div>
</h:body>
</html>

Listing 5-4     German template template.xhtml

Finally, we need to tell the index.xhtml Facelet which contract it should be working with. The <f:view> tag can be used as a container for all the JSF tags in a single page. This allows us to use global settings for the view – the locale to be used, for example, or the desired contract. The <f:view> tag possesses the attribute contracts, which can be assigned the name of the contract to be used. The value here should be set dynamically as the language of the user, which we can define using an EL expression. Within the EL expression, we have different predefined variables available to us. The variable view provides us with information about the current view, including the locale that is being used and its language. Modify the index.xhtml file as shown in ‎Listing 5-5.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:f="http://xmlns.jcp.org/jsf/core" 	
	xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
	<body>
		<f:view contracts="#{view.locale.language}">
			<ui:composition template="/template.xhtml">
				<ui:define name="content">
					<h1>#{msg['welcome.text']}</h1>
				</ui:define>
			</ui:composition>
		</f:view>
	</body>
</html>

Listing 5-5     Facelet index.xhtml

We can try the page out by restarting the runner and opening the provided link in a browser. Depending on your locale, you will receive either an English or a German greeting.

We have now completed all the necessary preliminary tasks and can begin working on our first use case!

Discussion

Use the message board below to give the authors your feedback or to discuss this page’s topic with other readers (in English please!). Please don’t expect the authors to answer directly, but they might update the content of this site according to your feedback.


  1. Hint: Use the Copy&Paste functinality of the context menu in the Codenvy IDE.