User Interface Design in ICEfaces 1.8: Part 2

Facelets templating

To implement the layout design, we use the Facelets templating that is officially a part of the JSF specification since release 2.0. This article will only have a look at certain parts of the Facelets technology. So, we will not discuss how to configure a web project to use Facelets. You can study the source code examples of this article, or have a look at the developer documentation (https://facelets.dev.java.net/nonav/docs/dev/docbook.html) and the articles section of the Facelets wiki (http://wiki.java.net/bin/view/Projects/FaceletsArticles)for further details.

The page template

First of all, we define a page template that follows our mockup design. For this, we reuse the HelloWorld(Facelets) application. You can import the WAR file now if you did not create a Facelets project.

For importing a WAR file, use the menu File | Import | Web | WAR file. In the dialog box, click on the Browse button and select the corresponding WAR file. Click on the Finish button to start the import. The run configuration is done. However, you do not have to configure the Jetty server again. Instead, it can be simply selected as your target.

We start coding with a new XHTML file in the WebContent folder. Use the menu File | New | Other | Web | HTML Page and click on the Next button. Use page-template.xhtml for File name in the next dialog. Click on the Next button again and choose New ICEfaces Facelets.xhtml File (.xhtml). Click on the Finish button to create the file.

The structure of the page is almost pure HTML. This is an advantage when using Facelets. The handling of pages is easier and can even be done with a standard HTML editor.

The generated code is not what we need. If you try to run this, you will get an error because the header.xhtml file is missing in the project. So, we delete the code between the <body> tags and add the basic structure for the templating. The changed code looks like this:

We change the <body> part to a table structure. You may wonder why we use a <table> for the layout, and even the align attribute, when there is a <div> tag and CSS. The answer is pragmatism. We do not follow the doctrine because we want to get a clean code and keep things simple. If you have a look at the insufficient CSS support of the Internet Explorer family and the necessary waste of time to get things running, it makes no sense to do so. The CSS support in Internet Explorer is a good example of the violation of user expectations.

We define four rows in the table to follow our layout design. You may have recognized that the <title> tag still has its <ui:insert> definition. This is the Facelets tag we use to tell the templating where we want to insert our page-specific code. To separate the different insert areas from each other, the <ui:insert> has a name attribute.

We substitute the comments with the <ui:insert> definitions, so that the templating can do the replacements:

The <ui:insert> tag allows us to set defaults that are used if we do not define something for replacement. Everything defined between <ui:insert> and </ui:insert> will then be shown instead. We will use this to define a standard behavior of a page that can be overwritten, if necessary. Additionally, this allows us to give hints in the rendering output if something that should be defined in a page is missing.

The header, the main navigation, and the footer now have defaults. For the page title and the page content, there are messages that ask for an explicit definition. The header has a reference to an image. Add any image you like to the WebContent and adapt the url attribute of the <ice:graphicImage> tag, if necessary. The example project for this article will show the ICEcube logo. It is the logo that is shown in the mockup above. The <ice:menuBar> tag has to be surrounded by a <ice:form> tag, so that the JSF actions of the menu entries can be processed. Additionally, we need a reference to one of the ICEfaces default skins in the <head> tag to get a correct menu presentation. We take the Royale skin here.

If you do not know what the Royale skin looks like, you can have a look at the ICEfaces Component Showcase (http://component-showcase.icefaces.org) and select it in the combo box on the top left. After your selection, all components present themselves in this skin definition.

Using the template

A productive page template has a lot more to define and is also different in its structure. References to your own CSS, JavaScript, or FavIcon files are missing here. The page template would be unmaintainable soon if we were to manage the pull-down menu this way.

However, we will primarily look at the basics here. So, we keep the page template for now. Next, we adapt the existing ICEfacesPage1.xhtml to use the page template for its rendering.

We keep the Hello World! output and use the new page template to give some decoration to it. First of all, we need a reference to the page template so that the templating knows that it has to manage the page. As the page template defines the page structure, we no longer need a <head> tag definition.

You may recognize <ui:insert> in the <title> tag. This is indeed the code we normally use in a page template. Facelets has rendered the content in between because it did not find a replacement tag. Theoretically, you are free to define such statements in any location of your code. However, this is not recommended. Facelets has a look at the complete code base and matches pairs of corresponding name attribute definitions between <ui:insert name="..."> and <ui:define name="..."> tags.

We can see our friendly reminders for the missing title and the missing content. The header, the main navigation, and the footer are rendered as expected. The structure of the template seems to be valid, although we recognize that a CSS fle is necessary to define some space between the rows of our layout table.

However, something is wrong. Any idea what it is? If you have a look at the hello-world.xhtml again, you can find our Hello World! output; but this cannot be found in the rendering result. As we use the page template, we have to tell the templating where something has to be rendered in the page. However, we did not do this for our Hello World! output.

The following code defines the missing <ui:define> tag and skips the <div> and <ice:form> tags that are not really necessary here:

The templating in ICEfusion

ICEfusion already delivers a standardized templating. This is based on experiences from productive development. We will use this for ICEcube and extend it. To familiarize you with the ideas, we will first have a look at some of the implementation details.

Running ICEfusion

There is a ZIP archive for this article that delivers release 1.0.1 of ICEfusion. You can use this distribution for the following source code studies. For this, take care that the MySQL server is already running.

You can use the following command in Maven 2 to build the project in the pom.xml folder (or run first-time-run.bat):

mvn install

Ignore the errors that are shown during running the tests. The important thing with this run is the initialization of the database. After this, you can run Maven 2 again using the following command (or run run.bat):

mvn clean install jetty:run-war -Dmaven.test.skip=true

The tests will be skipped to prevent the errors and the Maven 2 internal Jetty is used for deployment. Use http://localhost:8080 in your web browser to have a look at the application.

The ICEfusion files

The ICEfusion project follows the Maven 2 conventions. So, the ICEfusion extensions to AppFuse can be found in /icefusion/src/main/webapp/icefusion/. In this folder, you can find the Spring configuration files. Additionally, there are folders for JavaScripts (/scripts/), ICEfaces skins (/styles/), and the Facelets templating (/taglibs/). The folder names follow the AppFuse conventions.

The page layout files can be found in /icefusion/src/main/webapp/icefusion/taglibs/commons/. We'll have a look at the page template first (/icefusion/src/main/webapp/icefusion/taglibs/commons/page.xhtml).

The code is similar to our example above. However, it references skin definitions that are varied via an Expression Language reference to a Spring bean, context.skin. The bean delivers a folder name. Each of the possible skin folders has the same folder and file structure. This allows us to switch between them without any adaptation in the templating.

Another variation is the use of custom Facelets tags. We use these to define the different sections in the page layout. This is primarily done for maintenance purposes. In contrast to our Facelets example, the menu can then be managed in a dedicated file.

The new tags are managed via a Facelets tag library. We use the icefusion namespace to reference the tags.

Next, we will look at the code of the icefusion tags. The header can be found at /icefusion/src/main/webapp/icefusion/taglibs/commons/header.xhtml:

This looks almost like our example, although the logo is managed via the skin selection. You may recognize the <ui:component> tag. This describes where the code for a Facelets tag starts and stops. Everything outside this tag is ignored.

The main navigation is defined in /icefusion/src/main/webapp/icefusion/taglibs/commons/navigation.xhtml:

The navigation tag already considers the mockup design. We have definitions for menu and additional menu icons. The menu definition allows you to choose between a static menu definition and a dynamic one.

The corresponding code for the static menu tag can be found in /icefusion/src/main/webapp/icefusion/taglibs/commons/menu.xhtml:

This footer also defines a copyright hint. It is extended with a link to the license text.

The following screenshot shows how the rendered result looks:

We would adapt the ICEfusion code base to create our ICEcube base from it. The ICEcube code base will then be iteratively extended with the sample code.

Summary

The creation of desktop-like web applications is a challenging task. Following the principles of ergonomics is an important part on our way to a useful interface design. However, we have to expect several iterations before we get a suitable result. During this process, a mockup tool can help us develop page designs in a fast and easy way.The Facelets templating can be used to implement fexible and maintainable page designs. With ICEfusion, we get a production-ready templating implementation that can be used for the creation of ICEcube.

Alerts & Offers

Series & Level

We understand your time is important. Uniquely amongst the major publishers, we seek to develop and publish the broadest range of learning and information products on each technology. Every Packt product delivers a specific learning pathway, broadly defined by the Series type. This structured approach enables you to select the pathway which best suits your knowledge level, learning style and task objectives.

Learning

As a new user, these step-by-step tutorial guides will give you all the practical skills necessary to become competent and efficient.

Beginner's Guide

Friendly, informal tutorials that provide a practical introduction using examples, activities, and challenges.

Essentials

Fast paced, concentrated introductions showing the quickest way to put the tool to work in the real world.

Cookbook

A collection of practical self-contained recipes that all users of the technology will find useful for building more powerful and reliable systems.

Blueprints

Guides you through the most common types of project you'll encounter, giving you end-to-end guidance on how to build your specific solution quickly and reliably.

Mastering

Take your skills to the next level with advanced tutorials that will give you confidence to master the tool's most powerful features.

Starting

Accessible to readers adopting the topic, these titles get you into the tool or technology so that you can become an effective user.

Progressing

Building on core skills you already have, these titles share solutions and expertise so you become a highly productive power user.