How do I conditionally render an <f:facet>?

I was able to solve this by swapping the facet out for an attribute. To summarize:

This works

<p:panel ...>
    <f:attribute name="footer" value="#{message}"/>
    <!-- ... -->
</p:panel>

But this doesn't work

<p:panel footer="#{message}">
    <!-- ... -->
</p:panel>

Neither does this

<p:panel ...>
    <f:facet name="footer">#{message}</f:facet>
    <!-- ... -->
</p:panel>

Nor this

<p:panel ...>
    <f:facet name="footer">
        <h:outputText value="#{message}" rendered="#{!empty message}"/>
    </f:facet>
    <!-- ... -->
</p:panel>

by "works" I mean:

"renders no footer — not just an empty footer — when #{message} is empty or null; otherwise, correctly renders the footer with the specified text."


PrimeFaces forum thread on this issue


You could declare a ui:param and let the template check the param while renderring.

The facet in the template could then be declared as:

<f:facet name="#{hideFooter == null or not hideFooter ? 'footer' : ''}">
     #{message}
</f:facet>

Any page can then declare this param

<ui:param name='hideFooter' value='#{some rule}' />

and set the appropriate rule for the param. For any page that does not declare the param, the footer will be displayed.


Here's what I did in trying to conditionally render a facet within a composite component.

<composite:interface>
    <composite:facet name="header" required="false" />
</composite:interface>
<composite:implementation>
    <p:panel>
        <c:if test="#{empty component.facets.header}" >
            <f:facet id="#{cc.attrs.id}_default_header" name="header">
            all sorts of stuff here
            </f:facet>
        </c:if>
        <c:if test="#{not empty component.facets.header}">
            <composite:insertFacet id="#{cc.attrs.id}_custom_header" name="header" />
        </c:if>
        <composite:insertChildren id="#{cc.attrs.id}_content"/>
    </p:panel>
</composite:implementation>

This let's the user of the composite component supply the header facet if they want, and if they don't, we supply a default. Obviously, instead of providing a default, you could simply not do anything.

This mixes c:if in jsf controls, but we didn't see any adverse effects.