As it was mentioned previously, rich:panel shows the header only if the facet name="header" is defined. Otherwise, it is just omitted.

In case the header presents, its content is wrapped with div:

  <div class="rich-panel-header #{compositeComponent.attrs.headerClass}">
   <composite:insertFacet name="header"/>
  </div>

What happens in the code above if panel has no header facet on the xhtml page? PDL processor just inserts nothing inside the div without any notes (the same happens, BWT if you have a typo in the facet name). However, it is not what we need, as we need to omit the whole div.

In general, it looks like a common use case: if facet is missing, the whole block that represents the facet in the final layout is omitted. I did not find anything like that in the pdldocs. The second idea was to use a conditional operation.

The following EL returns true if header facet presents. Otherwise, it returns false.

#{! empty compositeComponent.facets.header}

Thus, the following snippet is a solution:

<c:if test="#{! empty compositeComponent.facets.header}">
  <div class="rich-panel-header #{compositeComponent.attrs.headerClass}">
   <composite:insertFacet name="header"/>
  </div>
</c:if>

However, it does not work. There is a good explanation why it does not work in this article:

http://www.ilikespam.com/blog/c:foreach-vs-ui:repeat-in-facelets

When the c:if test is evaluated the compositeComponent.facets is always empty. Hence, a header is not shown even when it presents. The solution is also in that article. We will use ui:fragment. The final code that is sensible to a header facet is following:

<!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"
      xmlns:c="http://java.sun.com/jstl/core"
      xmlns:composite="http://java.sun.com/jsf/composite">
<head>

<title>panel</title>

</head>

<body>

<composite:interface>
    <composite:attribute name="style" required="false"/>
    <composite:attribute name="styleClass" required="false"/>
    <composite:attribute name="headerClass" required="false"/>
    <composite:attribute name="bodyClass" required="false"/>
</composite:interface>



<composite:implementation>
    <h:outputStylesheet name="rich/css/panel.css" />

 <div class="rich-panel #{compositeComponent.attrs.styleClass}"
            style="#{compositeComponent.attrs.style}">

  <ui:fragment rendered="#{! empty compositeComponent.facets.header}">
   <div class="rich-panel-header #{compositeComponent.attrs.headerClass}">
    <composite:insertFacet name="header"/>
   </div>
  </ui:fragment>
 
  <div class="rich-panel-body #{compositeComponent.attrs.bodyClass}" > 
   
   <composite:insertChildren />
  </div> 

 </div>
</composite:implementation>

</body>

</html>
update January 19, 2009:

Today we have been notified that it will be possible to use c:if as well as other jstl like tags for conditional operations inside the templates.


Back to top