[jsr-314-open] composite:insertFacet target facet name
Alexander Smirnov
asmirnov at exadel.com
Fri Sep 25 14:00:22 EDT 2009
Nice catch, that is meet my expectations too.
On 09/24/2009 03:55 PM, Andy Schwartz wrote:
> Gang -
>
> I have been spending a lot of time thinking about this topic and reading
> the doc/looking at the source code. I can now say that I definitely
> understand the difference between composite:insertFacet and
> composite:renderFacet. :-) However, I am still confused about why we
> decided to go with two separate tags and wanted to share my thoughts.
>
> FWIW, I realize that it is like a year late to be bringing this up, but
> thought it was important to discuss even if our options are limited at
> this point.
>
> Let's start by taking a look at composite:insertFacet:
>
> <composite:implementation>
> <h:panelGrid>
> <composite:insertFacet name="caption"/>
> </h:panelGrid>
> </composite:implementation>
>
> In the above case, the component specified for the "caption" facet ends
> up in the facet map of the h:panelGrid component. This has certain
> implications - eg. the component's parent property will point to the
> h:panelGrid instead of the composite component. If we happen to insert
> the facet into a NamingContainer, the client id will reflect this.
>
> Currently we provide no way to insert a composite component's facet into
> one of the composite's implementation components as a plain old
> (non-facet) child. So, if instead of inserting the "caption" facet as a
> facet on an h:panelGrid, I wanted to insert it as a (non-facet) child of
> an h:panelGroup, eg:
>
> <composite:implementation>
> <h:panelGroup>
>
> <!-- Insert the facet as a direct child here -->
>
> </h:panelGroup>
> </composite:implementation>
>
> I cannot do that. Or, at least, I cannot do that with the same semantics
> as <composite:insertFacet>, where the component specified via the facet
> ends up as a child of the containing component (the h:panelGroup).
>
> I can, however, use composite:renderFacet:
>
> <composite:implementation>
> <h:panelGroup>
> <composite:renderFacet name="caption"/>
> </h:panelGroup>
> </composite:implementation>
>
> This will cause the facet to be rendered as a child of the h:panelGroup,
> but without being a child of the h:panelGroup.
>
> This raises a number of questions. Why do we re-parent the facet
> component when we want the component to be used by the parent component
> as a facet, but not when we want the component to be used by the parent
> as a direct child? Is there a reason why we need to treat the direct
> child case differently (not re-parent) than the facet case (re-parent)?
> Is there some benefit to having subtly different behavior between these
> two cases?
>
> My feeling is that the good old Facelets ui:insert tag got this right.
> Facelets uses a single tag to handle insertion of ui:define'd components
> into the template, regardless of whether the components are being
> inserted as facets or directly children. So, for example, assuming I've
> got a template that allows insertion of a "foo" component, I can do
> either this:
>
> <h:panelGrid>
> <f:facet name="caption">
> <!-- Insert the "foo" component into the "caption" facet -->
> <ui:insert name="foo"/>
> </f:facet>
> </h:panelGrid>
>
>
> Or this:
>
> <h:panelGroup>
> <!-- Insert the "foo" component as a non-facet child -->
> <ui:insert name="foo"/>
> </h:panelGroup>
>
>
> While the first case inserts the component as a facet and the second as
> a direct child, both have the same semantics - ie. in both cases the
> component that is being inserted ends up as a child of the parent
> component that the child is being inserted into.
>
> Actually, Facelets provides an API that is specifically designed to
> handle this type of insertion: TemplateClient. The TemplateClient API
> allows for clean/efficient insertion of included content into templates.
> I believe that ui:define/ui:insert use this to insert included content
> directly into the target location, avoiding the need to re-locate the
> included components from one parent to another. This has benefits when
> re-applying tags over a restored component tree, since there is no need
> to repeatedly re-create (or re-locate) these components.
>
> After thinking this through, one other question that I am left with is:
> Is there a reason why we did not follow the ui:insert approach?
>
> Yes, I realize that this is a moot point now, and no reason to dwell on
> this, but I am still curious as to whether there were
> limitations/problems with the ui:insert mechanism that prevented us from
> following this precedent.
>
> If we had the ability to revisit the design now, my preferred solution
> would be to:
>
> 1. Deprecate/remove composite:renderFacet.
> 2. Re-spec composite:insertFacet to match the behavior of ui:insert.
>
> I prefer this approach because I feel that we should share a single
> insertion behavior across all of these use cases. The fact that we have
> 3 subtly different mechanisms is, well... bad. I also think that the
> ui:insert approach has already been proven, which is in part why I favor
> that approach.
>
> Of course, I don't imagine that we have the ability to make this change
> given that the JSF 2.0 spec has been final for some time now, and this
> would be a significant change.
>
> I suppose my second choice would be to deprecate both
> composite:renderFacet/composite:insertFacet in JSF 2.1 and replace both
> of these with a new composite:insert tag that matches ui:insert behavior.
>
> Getting back to our original problem of not having control over the
> "target" facet name:
>
>> If the spec does not yet provide a solution for this, I think that we
>> could/should solve this in one of two ways:
>>
>> 1. Add an attribute to composite:insertFacet that allows a target
>> facet name to be specified:
>>
>> <h:panelGrid>
>> <composite:insertFacet name="backupCaption" targetName="caption"/>
>> </h:panelGrid>
>>
>> 2. Specify that the target facet name can be picked up from a wrapping
>> <f:facet> tag:
>>
>> <h:panelGrid>
>> <f:facet name="caption">
>> <composite:insertFacet name="backupCaption"/>
>> </f:facet>
>> </h:panelGrid>
>
> I still prefer #1 as this is closer to ui:insert behavior, but given
> that I have more fundamental reservations about
> composite:insertFacet/composite:renderFacet, I don't feel especially
> strongly about forcing #1 if people prefer #2.
>
> Andy
>
> Ken Paulsen wrote:
>>
>> When / where should this discussion take place? Do we want to have a
>> call for this?
>>
>> In addition to this issue, Alexander raised the issue that
>> f:insertFacet and f:renderFacet are confusing. Not sure if there's
>> anything we can do resolve this at this point, but minimally, it would
>> be worth ensuring the EG members understand the difference (which IMO,
>> is huge). In hindsight, f:insertFacet probably should have been
>> f:attachFacet, and of course had an optional "target" attribute for
>> Andy's case.
>>
>> Ken
>>
>> Andy Schwartz wrote:
>>> Thanks Ed -
>>>
>>> Ed Burns wrote:
>>>>
>>>> I happen to prefer #1, but everyone else favors #2, we'll go with #2.
>>>
>>> Seems like some people prefer #2 as well, so perhaps this needs more
>>> discussion.
>>>
>>>> Andy, can you please file a spec issue and share the number with the
>>>> group? Once you have it, I'll add an entry in the changelog wiki.
>>>>
>>>
>>> Sorry for taking so long to follow up on this. I have logged the
>>> following spec issue:
>>>
>>> https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=631
>>>
>>>
>>> Andy
>>>
>>>
>
More information about the jsr-314-open-mirror
mailing list