Template based web application with JSF


In this article we will demonstrate how you can create template in the JSF based web application. Creating template really helps if you want to repeat several things for the various pages, but also want to be able to have flexiblity to modify things whenever required.

Tools Used: Eclipse JavaEE - Juno, Wildfly 8.1.0

In this tutorial we will create a JSF based template which will not only help to reuse the code but also prevent the code duplication. Templates are common for any kind of application to prevent the wastage of time and efforts in this tutorial we will use the simplest way to convert a web page created with JSF and bootstrap structure into a template with various parts.

Series Index:

We are using a page with the form and table, which is decorated with the basic structure of the bootstrap framework. The page us created in JSF(please see previous articles from the index to see the page creation). The page code currently looks like this:


<!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:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"> 
<h:head>
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1" />
	<meta http-equiv="X-UA-Conpatible" content="IE=edge" />
	<h:outputStylesheet library="css" name="bootstrap.min.css"></h:outputStylesheet>
	<title>Demo Web</title>
</h:head> 
<h:body> 
	<div class="container">
		<div class="navbar navbar-inverse">
			<div class="navbar-brand">
				DEMO WEB
			</div>
		</div>
		<div class="row">
			<div class="col-xs-12">
				<h:form styleClass="form-horizontal">
					<div class="form-group">
						<h:outputLabel value="First Name" styleClass="control-label col-sm-2"/>
						<div class="col-sm-10">
							<h:inputText value="#{studentMB.firstName}" styleClass="form-control"/>
						</div>
					</div>
					<div class="form-group">
						<h:outputLabel value="Last Name" styleClass="control-label col-sm-2"/>
						<div class="col-sm-10">
							<h:inputText value="#{studentMB.lastName}" styleClass="form-control"/>
						</div>
					</div>
					<div class="form-group">
						<h:outputLabel value="Standerd" styleClass="control-label col-sm-2"/>
						<div class="col-sm-10">
							<h:inputText value="#{studentMB.standerd}" styleClass="form-control"/>
						</div>
					</div>
					<div class="form-group">
						<div class="col-sm-offset-2 col-sm-10">
							<c:choose>
								<c:when test="#{studentMB.id > 0 }">
									<h:inputHidden value="#{studentMB.id}" />
									<h:commandButton action="#{studentMB.updateStudent()}" value="Update" styleClass="btn btn-default"/>
								</c:when>
									<c:otherwise>
									<h:commandButton action="#{studentMB.createStudent()}" value="Create" styleClass="btn btn-default"/>
								</c:otherwise>
							</c:choose>
						</div>
					</div>
				</h:form>
				<table class="table table-bordered table-striped">
					<thead>
						<tr>
							<th>Name</th>
							<th>Standerd</th>
							<th></th>
							<th></th>
						</tr>
					</thead>
					<tbody>
						<ui:repeat var="stud" value="#{studentMB.getAllStudents()}">
							<tr>
								<td>#{stud.firstName} #{stud.lastName}</td>
								<td>#{stud.standerd}</td>
								<td>
									<h:form>
										<h:commandLink action="#{studentMB.getStudent(stud.id)}" >
											<i class="glyphicon glyphicon-edit"></i>
										</h:commandLink>
									</h:form>
								</td>
								<td>
									<h:form>
										<h:commandLink action="#{studentMB.deleteStudent(stud.id)}">
											<i class="glyphicon glyphicon-trash"></i>
										</h:commandLink>
									</h:form>
								</td>
							</tr>
						</ui:repeat>
					</tbody>
				</table>
			</div>
		</div>
	</div>
</h:body> 
</html>

Now the trouble is that this is only one page, but in a real world application there are so many pages and by looking at this page structure we can clearly tell that the page will need to repeat the similar code(header or footer part) on several pages in the overall application. Thus we want to prevent the code duplication and reduce the coding efforts too. So finally we need a template which could be used in overall application.

Creation of template is very easy in JSF based web application, all you need to figure out is which part you want to keep common and which to repeat or provide flexibility to change. So we are creating a template named common-template.xhtml and we place it under directory templates under web content directory.

Key part of any template is to mark the places which are eligible for overriding. However in this case we are going to create a template which provide good flexibility for the overriding of the template elements.

 

JSF provide us with user interface(ui:) tags which helps to create a template. Basic theory is to prepare a page structure and provide the container created with ui:insert tags which hold some default code as well as provide the flexibility of replacing the default code from the page which is using the template. Our template which we are going to create for the code reuse from above code, will look like this:


<!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:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"> 

<h:head>
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1" />
	<meta http-equiv="X-UA-Conpatible" content="IE=edge" />
	<h:outputStylesheet library="css" name="bootstrap.min1.css"></h:outputStylesheet>
	<title>
		<ui:insert name="title">Demo Web</ui:insert>
	</title>
</h:head> 
<h:body> 
	<div class="container">
		<ui:insert name="header">
			<div class="navbar navbar-inverse">
				<div class="navbar-brand">
					DEMO WEB
				</div>
			</div>
		</ui:insert>
		<ui:insert name="content">No Content!</ui:insert>
		<ui:insert name="footer">
			© copyright DEMO WEB.
		</ui:insert>
		<ui:insert name="scripts"></ui:insert>
	</div>
</h:body> 
</html>

In the code above we have moved the common part which is the HEAD part in to the template because it will remain same for every page using the template, however the page title is likely to change with every page thus we mark a flexibility option here with ui:insert with name title. When we will modify the student.xhtml(original page) to use the template we will show you how to use this title module of template.

Further we have created place for header, However we have specified default implementation too. In this case we have a default implementation but we also hold the flexibility to override the default implementation. Further we define holder elements(ui:insert) for content, footer and scripts. We like to specify the script template too, However we specify the common scripts in template but it is always good to provide a flexibility to add any more scripts which may be page specific.

The student page is now much lighter as most of the re usable code has been moved to the template file. Thus now we only need to override the default content of body of template structure with the main body of the student.xhtml. In student.xhtml we first specify the use of template by using ui:composition tag instead of all the bulky html, head and body, we only need to specify the ui:composition as the container of the file, inside this composition we can override any template module we want by using ui:define tag, with the name of template module we want to override.

Thus when we implement the title and body of the template in student.xhtml the page would look like this.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<ui:composition template="templates/common-template.xhtml"
	 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:c="http://java.sun.com/jsp/jstl/core"> 
<ui:define name="title">Students</ui:define>
<ui:define name="content">
		<div class="row">
			<div class="col-xs-12">
					<h:form styleClass="form-horizontal">
						<div class="form-group">
							<h:outputLabel value="First Name" styleClass="control-label col-sm-2"/>
							<div class="col-sm-10">
								<h:inputText value="#{studentMB.firstName}" styleClass="form-control"/>
							</div>
						</div>
						<div class="form-group">
							<h:outputLabel value="Last Name" styleClass="control-label col-sm-2"/>
							<div class="col-sm-10">
								<h:inputText value="#{studentMB.lastName}" styleClass="form-control"/>
							</div>
						</div>
						<div class="form-group">
							<h:outputLabel value="Standerd" styleClass="control-label col-sm-2"/>
							<div class="col-sm-10">
								<h:inputText value="#{studentMB.standerd}" styleClass="form-control"/>
							</div>
						</div>
						<div class="form-group">
							<div class="col-sm-offset-2 col-sm-10">
								<c:choose>
									<c:when test="#{studentMB.id > 0 }">
										<h:inputHidden value="#{studentMB.id}" />
										<h:commandButton action="#{studentMB.updateStudent()}" value="Update" styleClass="btn btn-default"/>
									</c:when>
									<c:otherwise>
										<h:commandButton action="#{studentMB.createStudent()}" value="Create" styleClass="btn btn-default"/>
									</c:otherwise>
								</c:choose>
							</div>
						</div>
					</h:form>
					<table class="table table-bordered table-striped">
						<thead>
							<tr>
								<th>Name</th>
								<th>Standerd</th>
								<th></th>
								<th></th>
							</tr>
						</thead>
						<tbody>
							<ui:repeat var="stud" value="#{studentMB.getAllStudents()}">
								<tr>
									<td>#{stud.firstName} #{stud.lastName}</td>
									<td>#{stud.standerd}</td>
									<td>
										<h:form>
											<h:commandLink action="#{studentMB.getStudent(stud.id)}" >
												<i class="glyphicon glyphicon-edit"></i>
											</h:commandLink>
										</h:form>
									</td>
									<td>
										<h:form>
											<h:commandLink action="#{studentMB.deleteStudent(stud.id)}">
												<i class="glyphicon glyphicon-trash"></i>
											</h:commandLink>
										</h:form>
									</td>
								</tr>
							</ui:repeat>
						</tbody>
					</table>
			</div>
		</div>
	</ui:define>
</ui:composition>

So as you can see we have specified the template used in the ui:composition and then defined the modules using ui:define. This is how we create template based structure in JSF. Please note that the Header and the footer remains the same as we haven't modified any of these.

template based view