No according to the documentation/implementation <f:insertFacet> applies a facet that was defined elsewhere (i.e. from the page author) to a child component of a composite component.  In other words, it calls:

    childcomponent.getFacets().put(name, facet)
;

If we keep that behavior, our only real option is #1:

   <composite:insertFacet name="backupCaption" targetName="caption"/>

Otherwise we're forced to change the behavior of what the tag does to manipulate the "VAST" meta-data structure (which afaik doesn't yet exist -- but perhaps can somehow be made to work reliably).  This would allow use cases where the facet is not treated as a facet, but as a way to specify a component... which can then be passed in as a facet, placed a child component, etc.  This leads us "close" to the functionality of "f:renderFacet"... but not quite as it doesn't add the child (which would manipulate the id, etc.)....

So, I think #2 is a very dangerous direction to go w/o putting some thought into 1) what we're trying to solve; 2) the impact of our solution.

Ken



Dan Allen wrote:

I suppose it depends on whether insertFacet attaches a facet to the parent component or whether it inserts the contents of the facet inline. I suspect the latter. In that case, you woud need to wrap insertFacet in <f:facet>, right?

- Dan Allen

Sent from my Android-powered G1 phone:
An open platform for carriers, developers
and consumers.

On Sep 15, 2009 6:43 PM, "Andy Schwartz" <andy.schwartz@oracle.com> wrote:

Gang -

While looking at #{cc} expression handling, I played around with some simple composite components and noticed the following behavior.

If I define a composite component, foo:outer, that accepts a facet:

<composite:interface>
 <composite:facet name="caption"/>
</composite:interface>

And then use the component, specifying the facet:

              <foo:outer>
                <f:facet name="caption">
                  <h:outputText value="Hello, Facet! (Outer)"/>
                </f:facet>
              </foo:outer>


I find that things work as expected if I render the facet in the foo:outer implementation:

<composite:implementation>
 <composite:renderFacet name="caption"/>
</composite:implementation>


And also work just fine if I pass the facet into a Java-based (non-composite) component:

<composite:implementation>
 <h:panelGrid>
  <composite:insertFacet name="caption"/>
 </h:panelGrid>
</composite:implementation>


However, if I define a second component, foo:inner, that exposes the same facet:

<composite:interface>
 <composite:facet name="caption"/>
</composite:interface>

<composite:implementation>
 <composite:renderFacet name="caption"/>
</composite:implementation>

And then attempt to pass the facet into the foo:inner component from the foo:outer implementation:

<composite:implementation>
 <foo:inner>
  <composite:insertFacet name="caption"/>
 </foo:inner>
</composite:implementation>


My expectation is that the facet would be inserted in to the foo:inner composite component (via the <composite:insertFacet name="caption">) and then rendered by the foo:inner implementation (via the <composite:renderFacet name="caption">).  However, the facet do contents do not appear in the rendered output.

I wasn't sure whether this is a spec issue, implementation or user error, and have not had a chance to debug further.  Want to raise this here in case anyone could comment.

FWIW, this is running against the Mojarra trunk.  I have not tested MyFaces.  (I have attached the two composite components.)

Andy