Combining MyFaces, Tiles 2, and Tomahawk jscookmenu

March 19, 2010 at 3:14 am | Posted in jsf | 5 Comments
Tags: , , , , , ,

I had this jsf project has common page parts (such as headers, footers, etc,) and menus like the ones on top your your desktop apps.

Having developed struts project before, Tiles was my choice of templating framework which is already a separate project known as Apache Tiles.

There are lots of javascript menus out there such as JSCookMenu and JQuery menu plugin but none of them were easy to integrate with JSF. So I used Tomahawk jscookmenu because of its integration with JSF navigations and actions.

I thought combining MyFaces, Tiles 2, and Tomahawk, was a bit of a challenge. Good thing I checked out samples from the svn repository http://myfaces.apache.org/tomahawk/source-repository.html for the Tiles integration with JspTilesTwoViewHandlerImpl. This combination was a big help in our project making page templating easier and more manageable.

So, I created a sample starter application combining these three technologies.

The finished product can be downloaded at this link http://dl.dropbox.com/u/1750383/myfaces-tiles-jscookmenu.war

Frameworks Used

For this starter project, these technologies were used.

MyFaces 1.2http://myfaces.apache.org/core12/index.html

Why MyFaces, not Mojarra? Well, tiles definition name as jsf page was a MyFaces only feature. For example <definition name=”/launch.tiles” …> in the configuration can be viewed as /launch.faces in application. A workaround in Mojarra implementation was to code each jsp with tiles tags much like using the old <jsp:incude> tag. If you want tiles-like templating in Mojarra, better use facelets. MyFaces 1.2 was used simply because we’ll use Tomahawk for JSF 1.2. As of this writing there is no Tomahawk for JSF 2.0 released yet.

Apache Tiles 2.0.5http://tiles.apache.org/

Tomahawk tiles sample from the trunk repository uses version 2.0.5. That was the version is where tomahawk tiles integration was tested.

MyFaces Tomahawkhttp://myfaces.apache.org/tomahawk-project/tomahawk12/index.html

We’ll use its tiles integration, and the jscookmenu component.

I assume that you have a basic knowledge of JSF especially its configurations because this setup takes a lot of configuration. The rest is just plain jsf. Use your favorited IDE and create a new dynamic web project.

Project Setup

/WEB-INF/lib

commons-beanutils-1.7.0.jar
commons-codec-1.3.jar
commons-collections-3.2.jar
commons-digester-1.8.jar
commons-discovery-0.4.jar
commons-fileupload.jar
commons-lang.jar
commons-logging-1.1.1.jar
jstl.jar
myfaces-api-1.2.7.jar
myfaces-impl-1.2.7.jar
standard.jar
tiles-api-2.0.5.jar
tiles-core-2.0.5.jar
tiles-jsp-2.0.5.jar
tomahawk12-1.1.9.jar

/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>myfaces-tiles-jscookmenu</display-name>
  <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>

  <!-- Make it sure to add myfaces servlet to make use of MyFacesExtensions Filter -->
  <servlet>
    <servlet-name>faces</servlet-name>
    <servlet-class>org.apache.myfaces.webapp.MyFacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>faces</servlet-name>
    <url-pattern>*.faces</url-pattern>
  </servlet-mapping>
  <listener>
    <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
  </listener>

  <!-- APACHE TILES ================================================= -->
  <context-param>
    <param-name>tiles-definitions</param-name>
    <param-value>/WEB-INF/tiles.xml</param-value>
  </context-param>

  <!-- MYFACES EXTENSIONS ========================================== -->
  <!-- This extensions are required for jscookmenu -->

  <filter>
    <filter-name>MyFacesExtensionsFilter</filter-name>
    <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
  </filter>
  <!--
    extension mapping for adding <script/>, <link/>, and other resource
    tags to JSF-pages
  -->
  <filter-mapping>
    <filter-name>MyFacesExtensionsFilter</filter-name>
    <url-pattern>*.faces</url-pattern>
  </filter-mapping>

  <!--
    extension mapping for serving page-independent resources
    (javascript, stylesheets, images, etc.)
  -->
  <filter-mapping>
    <filter-name>MyFacesExtensionsFilter</filter-name>
    <url-pattern>/faces/myFacesExtensionResource/*</url-pattern>
  </filter-mapping>

</web-app>

On the above configuration be sure to use MyFacesServlet as the jsf servlet. MyFacesExtensions require this. Also,it allows the jsf application to run on GlassFish application server while MyFaces is used as the implementation.

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>org.apache.myfaces.tomahawk.application.jsp.JspTilesTwoViewHandlerImpl</view-handler>
	</application>

</faces-config>

/WEB-INF/tiles.xml

<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
"http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>

  <definition name="default.main" template="/WEB-INF/tiles/main-layout.jsp">
    <put-attribute name="title" value="replace title" />
    <put-attribute name="header" value="/WEB-INF/tiles/default/header.jsp" />
    <put-attribute name="menu" value="/WEB-INF/tiles/default/menu.jsp" />
    <put-attribute name="content" value="/WEB-INF/tiles/default/body.jsp" />
    <put-attribute name="footer" value="/WEB-INF/tiles/default/footer.jsp" />
  </definition>

  <definition name="/default.tiles" extends="default.main">
  </definition>

</tiles-definitions>

From the tiles.xml configuration, the first definition is the root template. The <put> tags determines the location of the page parts. The latter definition extends the first definition but does not override anything. We just need the .tiles extension so that we can address default.tiles as default.faces when the server runs. The next code shows the root template.

/WEB-INF/tiles/main-layout.jsp

<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>

<f:view>
  <html>
  <head>
  <title><tiles:getAsString name="title" /></title>
  </head>
  <body>
  <center><h:panelGrid border="1" width="768">
    <h:panelGroup>
      <tiles:insertAttribute name="header" flush="false" />
    </h:panelGroup>
    <h:panelGroup>
      <tiles:insertAttribute name="menu" flush="false" />
    </h:panelGroup>
    <h:panelGroup>
      <tiles:insertAttribute name="content" flush="false" />
    </h:panelGroup>
    <h:panelGroup>
      <tiles:insertAttribute name="footer" flush="false" />
    </h:panelGroup>
  </h:panelGrid></center>
  </body>
  </html>
</f:view>

The <tiles:*> in the jsp are mapped to its definition in tiles.xml, default.main. <tiles:getAsString> gets the text value. <tiles:insertAttribute> gets the jsp value just like using a <jsp:include>. We set flush to false so that we import the full jsp text, not the processed result. The next pieces of source codes are the page parts to be inserted.

/WEB-INF/tiles/default/header.jsp

<div style="text-align: center; font-size: 24px">Header</div>

Next is where tomahawk jscookmenu comes in. It was a lot easier than mixing the code with javascripts, and the code still looks like a clean jsf plus it integrates well jsf actions. More info about jscookmenu at http://myfaces.apache.org/tomahawk-project/tomahawk/tagdoc/t_jscookMenu.html. The action attribute <t:navigationMenuItem> is an action outcome that can be used in the navigation rules in faces-config.

/WEB-INF/tiles/default/menu.jsp

<%@taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%>

<h:form>
  <t:jscookMenu layout="hbr" theme="ThemeOffice">
    <t:navigationMenuItem itemLabel="Menu 1">
      <t:navigationMenuItem itemLabel="Item 1.1" action="outcome1.1" />
      <t:navigationMenuItem itemLabel="Item 1.2" action="outcome1.2" />
    </t:navigationMenuItem>

    <t:navigationMenuItem itemLabel="Menu 2">
      <t:navigationMenuItem itemLabel="Item 2.1" action="outcome2.1" />
      <t:navigationMenuItem itemLabel="Item 2.2" action="outcome2.2" />
      <t:navigationMenuItem itemLabel="Menu 2.1">
        <t:navigationMenuItem itemLabel="Item 2.1.1" action="outcome2.1.1" />
        <t:navigationMenuItem itemLabel="Item 2.1.2" action="outcome2.1.2" />
      </t:navigationMenuItem>
    </t:navigationMenuItem>
  </t:jscookMenu>
</h:form>

/WEB-INF/tiles/default/body.jsp

<div align="center">Insert body here</div>

/WEB-INF/tiles/default/footer.jsp

<div style="text-align: center; font-size: 10px">footer</div>

Our starter project is done. Deploy the application a web server and go to http://localhost:<port>/<context-root>/default.faces depending on how you configured your web server. Mine was http://localhost:8080/myfaces-tiles-jscookmenu/default.faces.

Extending the Root Layout

We’ll write more pages by means of extending the root layout. We’ll define a home page, and two other pages. The home page extends the root page, and the other pages extend the home page. Here’s the updated tiles.xml

updated /WEB-INF/tiles.xml

<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
"http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>

  <definition name="default.main" template="/WEB-INF/tiles/main-layout.jsp">
    <put-attribute name="title" value="replace title" />
    <put-attribute name="header" value="/WEB-INF/tiles/default/header.jsp" />
    <put-attribute name="menu" value="/WEB-INF/tiles/default/menu.jsp" />
    <put-attribute name="content" value="/WEB-INF/tiles/default/body.jsp" />
    <put-attribute name="footer" value="/WEB-INF/tiles/default/footer.jsp" />
  </definition>

  <definition name="/default.tiles" extends="default.main">
  </definition>

  <!-- Sample ========================================================== -->
  <definition name="/sample/home.tiles" extends="default.main">
    <put-attribute name="title" value="Sample Home Page" />
    <put-attribute name="header" value="/WEB-INF/tiles/sample/header.jsp" />
    <put-attribute name="menu" value="/WEB-INF/tiles/sample/menu.jsp" />
    <put-attribute name="content" value="/WEB-INF/tiles/sample/home.jsp" />
    <put-attribute name="footer" value="/WEB-INF/tiles/sample/footer.jsp" />
  </definition>

  <definition name="/sample/page1.tiles" extends="/sample/home.tiles">
    <put-attribute name="title" value="Sample Page 1" />
    <put-attribute name="content" value="/WEB-INF/tiles/sample/page1.jsp" />
  </definition>

  <definition name="/sample/page2.tiles" extends="/sample/home.tiles">
    <put-attribute name="title" value="Sample Page 2" />
    <put-attribute name="content" value="/WEB-INF/tiles/sample/page2.jsp" />
  </definition>
</tiles-definitions>

updated 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>org.apache.myfaces.tomahawk.application.jsp.JspTilesTwoViewHandlerImpl</view-handler>
  </application>

  <!-- Sample -->
  <navigation-rule>
    <from-view-id>/sample/*</from-view-id>
    <navigation-case>
      <from-outcome>home</from-outcome>
      <to-view-id>/sample/home.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
      <from-outcome>page1</from-outcome>
      <to-view-id>/sample/page1.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
      <from-outcome>page2</from-outcome>
      <to-view-id>/sample/page2.jsp</to-view-id>
    </navigation-case>
  </navigation-rule>

</faces-config>

/WEB-INF/tiles/sample/header.jsp

<div style="text-align: center; font-size: 24px">MyFaces, Tiles 2, and JSCookMenu Example</div>

/WEB-INF/tiles/sample/menu.jsp

<%@taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%>

<h:form>
  <t:jscookMenu layout="hbr" theme="ThemeOffice">
    <t:navigationMenuItem itemLabel="Home" action="home" />

    <t:navigationMenuItem itemLabel="Pages">
      <t:navigationMenuItem itemLabel="Page 1" action="page1" />
      <t:navigationMenuItem itemLabel="Page 2" action="page2" />
    </t:navigationMenuItem>
  </t:jscookMenu>
</h:form>

/WEB-INF/tiles/sample/home.jsp

<h1>Hello World!</h1>
<h2>This is my home page!</h2>

/WEB-INF/tiles/sample/footer.jsp

<div style="text-align: center; font-size: 10px">Copyright &copy; 2010 sample</div>

/WEB-INF/tiles/sample/page1.jsp

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>

<h:outputText value="This is page 1" />
<f:verbatim><center></f:verbatim>
<h:panelGrid style="text-align: center; background-color: ORANGE">
  <h:outputText value="BREAK GLASS" style="font-size: 25px" />
  <h:outputText value="IN CASE OF FIRE" />
</h:panelGrid>
<f:verbatim></center></f:verbatim>

/WEB-INF/tiles/sample/page2.jsp

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>

<h:outputText value="This is page 2" />
<f:verbatim><center></f:verbatim>
  <h:panelGrid style="text-align: center; background-color: GREEN; color: WHITE">
    <h:outputText value="FIRE EXIT" style="font-size: 25px"/>
  </h:panelGrid>
<f:verbatim></center></f:verbatim>

That’s it. Deploy your application to a web server and go to http://localhost:8080/myfaces-tiles-jscookmenu/sample/home.faces.

homepage

page1


page2


The finished product can be downloaded at this link http://dl.dropbox.com/u/1750383/myfaces-tiles-jscookmenu.war

Advertisements

5 Comments »

RSS feed for comments on this post. TrackBack URI

  1. Very helpful. Thank you very much for sharing your knowledge with us.

  2. Very Interesting JSF components implementation. Thanks for the Ideas. Keep it up. More Power. Godbless.

  3. Its a great help. Thanks for sharing your ideas.Until next time. 🙂 GodBless!

  4. jerome how about in inputcalendar of tomahawk… I tried using it but it did not when you select a date…. what shall i do??

    • Well, this blog is not about tomahawk’s calendar tag but I give you advice on this. Some of the JSF extensions on Tomahawk import javascript libraries like prototype js and dojo toolkit. Tomahawk’s calendar uses prototype js that uses $ functions just like jQuery. Combining jQuery and prototype js will cause conflicts.

      If you combine jQuery with Tomahawk’s calendar that uses prototype js, make sure to solve conflicts. Here a link to solving jQuery conflict with other toolkits
      http://api.jquery.com/jQuery.noConflict/


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.
Entries and comments feeds.

%d bloggers like this: