Tuesday, November 8, 2011

Self InclusiveTemplating in JSF 2.0

Page template is a nice feature in JSF 2.0. Combined with EL 2.2, it is so powerful that you can do self inclusive templating in a production environment. Here is an example:

1) client file - index.xhtml:

    <ui:composition xmlns="http://www.w3.org/1999/xhtml"
         xmlns:ui="http://java.sun.com/jsf/facelets"
         xmlns:f="http://java.sun.com/jsf/core"
         xmlns:h="http://java.sun.com/jsf/html"
        
template="/templates/template.xhtml">

      
<ui:define name="title">Page Title</ui:define> 

       <ui:define name="body">Page Body</ui:define>
   </ui:composition>



Here it is using the template.xhtml as the template, then define 2 elements "title" and "body" to pass to template.xhtml.

2) template file - template.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:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets">
 

<h:head>
 <title><ui:insert name="title">Title</ui:insert></title>
 <ui:include src="/templates/header.xhtml"/> 

</h:head>
 

<h:body>
  <div id="col2" class="clearfix">

   <div id="col2a">
    <ui:insert name="body">Body</ui:insert>
    <ui:include src="/templates/footer.xhtml"/>
   </div>
 
   <div id="col2b">
    <div id="nav-container">
     <ul id="nav-main">
       <ui:include src="/templates/submenu.xhtml">
        <ui:param name="submenu" value="#{sessionSupport.menuService.getSubMenu(currentSectionUrl)}" />
        <ui:param name="level" value="1" />
      </ui:include>
     </ul>
    </div>
   </div>

  </div>
</h:body>
 

</html>


The two "ui:insert" are the place-holders for page title and body, which are provided from the client file (index.xhtml); "ui:include" pieces are convenient to include a few html snippets to make the code clean and neat. Among them submenu.xhtml is the most interesting one.


3) self inclusive snippet file - submenu.xhml:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
   xmlns:ui="http://java.sun.com/jsf/facelets"
   xmlns:h="http://java.sun.com/jsf/html"
   xmlns:c="http://java.sun.com/jsp/jstl/core">
 

<c:set var="url" value="#{sessionSupport.breadCrumbs[level+1].url}"/>
<c:set var="requestURI" value="#{sessionSupport.requestURI}" />

<c:forEach items="#{submenu}" var="menuItem" varStatus="status">

<c:choose>
<c:when test="#{sessionSupport.menuService.isSelf(menuItem, requestURI)}">
 <li class="active"><a href="#{menuItem.url}">#{menuItem.name}</a>
   <ul>
    <ui:include src="/templates/submenu.xhtml">
    <ui:param name="submenu" value="#{sessionSupport.getSubMenu(
url
)}"/>
    <ui:param name="level" value="#{level+1}" />
    </ui:include>
   </ul>
  </li>
</c:when>
<c:otherwise>
  <li><a href="#{menuItem.url}">#{menuItem.name}</a></li>
</c:otherwise>
</c:choose>
</c:forEach>


</ui:composition>



The code loops through the menu items at the current level and then calls itself, passing the sub-menu of the next level as a parameter, and then goes on and on, until it walks through the whole tree structure.

No comments:

Post a Comment