Skip to main content

Conventional UI design with Facelets and JSF 2.2

Posted by lamine_ba on October 3, 2011 at 1:54 PM PDT

 

An experience is relevant only if it can prevent you to repeat the same mistake.
Anonymous

Introduction

Make it compliant! Yes, Ladies and Gentlemen, Make it compliant! That is my tip of the day and the statement I woke up with today. Like many of you, I have read the Jsf-spec pdf file and as you may know, JSF 2.2 is coming with two major features : Faces Flows and Multi-templating. Did you see that it will be possible to package a Faces Flow and a template as a jar file, or as an exploded directory? And that it will be possible to offer faces flows and templates as re-usable components in a software repository, such as a maven repository ? In other words, the new vision of JSF is “drop in and go”. There is nothing wrong and suspicious in that strategy but I'm only curious to see how this will gonna happen if we haven't any conventions yet. You would be in a big dream if you think that my view can reuse your template if it does not bring well-known areas. Just take a look at this sample to be convinced :

Your Template

  1. <ui:insert name="windowTitle">
  2.         XEN Template
  3. </ui:insert>
  4.  
  5. <ui:insert name="top">
  6.         top design
  7. </ui:insert>
  8.  
  9. <ui:insert name="login-area">
  10.          login-area design
  11. </ui:insert>
  12.  
  13. <ui:insert name="search-area">
  14.         search-area design
  15. </ui:insert>
  16.  
  17. <ui:insert name="navigation">
  18. </ui:insert>
  19.  
  20. <ui:insert name="body">
  21. </ui:insert>
  22.  
  23. <ui:insert name="bottom">
  24.         bottom design
  25. </ui:insert>
  26.  

My view using another Template

  1. <ui:define name="title">
  2.         My View
  3. </ui:define>
  4.  
  5. <ui:define name="header">
  6.         header design
  7. </ui:define>
  8.  
  9. <ui:define name="login">
  10.          login design
  11. </ui:define>
  12.  
  13. <ui:define name="search">
  14.         search design
  15. </ui:define>
  16.  
  17. <ui:define name="menu">
  18.         menu design
  19. </ui:define>
  20.  
  21. <ui:define name="content">
  22.         content design
  23. </ui:define>
  24.  
  25. <ui:define name="footer">
  26.         footer design
  27. </ui:define>
  28.  

In other words, your template is not compliant with my application because you and I have chosen the stupid strategy of using a different name to name the same thing. Crazy no! I think it is high time to be homogeneous and to escape from this insanity by making our new components "compliant" with any JSF application . For the case of our templates, that is very easy. Let's design a template according to the basic structure of the user interface of a web application. Let's bring this simple contract and let's all use these well-know values : title, header, login, search, menu, content, footer. But if you want, we can even further reduce this list if we all agree that a view will only override the title and the content areas. And also if we all agree that the other areas minus the menu area must be designed statically in the template. Isn't it the whole idea behind customization? You don't like the design of the header, just go in the template and change it. But if you were a true web designer, you would know that this customization is even done with css. Here is now the strategy we are expecting to see in any template  :

  1. <div id="header">
  2.         common header design
  3. </div>
  4.  
  5.  
  6. <div id="footer">
  7.         common footer design
  8. </div>
  9.  

or 

  1. <div id="header">
  2.    <ui:insert name="header">
  3.         common header design
  4.    </ui:insert>
  5.  
  6. </div>
  7.  
  8.  
  9. <div id="footer">
  10.    <ui:insert name="footer">
  11.         common footer design
  12.    </ui:insert>
  13. </div>
  14.  

but not this 

  1. <div id="header">
  2.   <ui:include src="/header.xhtml"/>  
  3. </div>
  4.  
  5.  
  6. <div id="footer">
  7.    <ui:include src="/footer.xhtml"/>  
  8. </div>
  9.  

nor this

  1. <div id="header">
  2.   <ui:insert name="header"
  3.         <ui:include src="/header.xhtml"/>  
  4.   </ui:insert>
  5.  
  6. </div>
  7.  
  8.  
  9. <div id="footer">
  10.   <ui:insert name="footer"
  11.         <ui:include src="/footer.xhtml"/>  
  12.  </ui:insert>
  13. </div>
  14.  

The design technique above must only be applied for the menu area because a menu is the only thing a template cannot come with

  1. <div id="menu">
  2.  
  3.   <ui:insert name="menu"
  4.         <ui:include src="/menu.xhtml"/>  
  5.   </ui:insert>
  6.  
  7. </div>
  8.  

We are also expecting the menu to be designed like this, with <ul> and <li> 

menu.xhtml

  1. <ui:composition xmlns="http://www.w3.org/1999/xhtml"  
  2.      xmlns:h="http://java.sun.com/jsf/html"  
  3.      xmlns:ui="http://java.sun.com/jsf/facelets">
  4.                  
  5.      <ul>
  6.               <li>
  7.                         <h:link value="Home" outcome="index"/>
  8.                  </li>
  9.                
  10.                 <li>
  11.                         <h:link value="Templates" outcome="templates"/>
  12.                        
  13.                 </li>
  14.                
  15.                 <li>
  16.                         <h:link value="Gallery" outcome="gallery"/>
  17.                 </li>
  18.                
  19.                 <li>
  20.                         <h:link value="About" outcome="about"/>
  21.                 </li>
  22.                
  23.                 </ul>
  24.                        
  25.     </ui:composition>

So that a template author can give it its style and layout with css :

template.css

  1. #menu { height: 49px; width:978px;background: #FF7805  }
  2.  
  3. #menu ul { width: auto; float: right; list-style-type:none; }
  4.  
  5. #menu ul li{ margin: 0; padding: 0; height: 49px; float: left; position: relative; }
  6.  
  7. #menu ul li a{ color: #FFFFFF; font-weight: bold; text-decoration: none; }
  8.  
  9. #menu ul li a:hover{ background-color: rgb(245,235,207);color: #444444; }
  10.  

So that you can get according to the template the following menu :

or this one

If you are ready to follow these conventions, I'm ready to share all my templates with you and even this application ( http://jsfmtsystem.appspot.com/faces/templates.xhtml ) so that any of you can deploy it worldwide. If you download it, you will be able to manage your own repository through a nice web interface built with JSF and to share your templates with your users through REST. Yes, it has also a Template Service built with JAX-RS ( http://jsfmtsystem.appspot.com/services/templates )

Template Service (serving XML Representations)

  1. <templates>
  2.  
  3. <template>
  4. <id>1</id>
  5. <name>world_cup</name>
  6. <creationDate>2010-06-15</creationDate>
  7. <author>Themza Team</author>
  8. <authorEmail>templates@themza.com</authorEmail>
  9. <authorUrl>http://www.themza.com</authorUrl>
  10. <creationDate>2010-06-15</creationDate>
  11. <copyright>ThemZa 2009</copyright>
  12. <license>ThemZa TOS</license>
  13. <description>World Cup Heroes</description>
  14. <link>http://jsfmtsystem.appspot.com/services/templates/1</link>
  15. <thumbnail>http://jsfmtsystem.appspot.com/services/templates/1/thumbnail</thumbnail>
  16. <download>http://jsfmtsystem.appspot.com/services/templates/1/download</download>
  17.  
  18. </template>
  19.  
  20. ......
  21.  
  22. ......
  23.  
  24. </templates>

Build your own Template client

To make things funny, You can even build your own client or download my upcoming google android application to consume this service.

Using a Template Remotely

No need to download a template, your application can use it remotely. Isn't it the whole idea behind "Cloud"? You can also use this strategy to avoid resources duplication when your application is running in a clustered environment.

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app>
  3.  
  4.  
  5. <context-param>
  6.         <param-name>javax.faces.view.TEMPLATE</param-name>
  7.         <param-value>http://jsfmtsystem.appspot.com/services/templates/1</param-value>
  8. </context-param>
  9.  
  10.  
  11. </web-app>

Template Highlighting

The ui:insert tags can now be highlighted in the UI. Just send in your request the highlight parameter and set its value to true. You can see this feature in live here : Template Highlighting

Conclusion

Ladies and Gentlemen, that's all for today. But remember, having conventions is the only way for us to collaborate so that we can move fast.

AttachmentSize
mobile_client.PNG116.56 KB
template-highligh.PNG325.46 KB
Related Topics >>