Return-Path: Delivered-To: apmail-myfaces-dev-archive@www.apache.org Received: (qmail 35990 invoked from network); 26 May 2010 20:15:25 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 26 May 2010 20:15:25 -0000 Received: (qmail 59527 invoked by uid 500); 26 May 2010 20:15:25 -0000 Delivered-To: apmail-myfaces-dev-archive@myfaces.apache.org Received: (qmail 59441 invoked by uid 500); 26 May 2010 20:15:25 -0000 Mailing-List: contact dev-help@myfaces.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "MyFaces Development" Delivered-To: mailing list dev@myfaces.apache.org Received: (qmail 59433 invoked by uid 99); 26 May 2010 20:15:25 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 26 May 2010 20:15:25 +0000 X-ASF-Spam-Status: No, hits=-0.7 required=10.0 tests=AWL,FREEMAIL_FROM,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of andy.g.schwartz@gmail.com designates 209.85.160.181 as permitted sender) Received: from [209.85.160.181] (HELO mail-gy0-f181.google.com) (209.85.160.181) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 26 May 2010 20:15:19 +0000 Received: by gyg8 with SMTP id 8so3941964gyg.12 for ; Wed, 26 May 2010 13:14:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:in-reply-to :references:date:message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=j6+TkciN/e5Fil2BsGbjsNsmPD3UQZYGywEtUTRGu0Q=; b=ILPJEMCkDVH1TIAoBKPpZ6zZXS6xjKIOraDDXQH6U8Pk6j47Mh+S7qvmg7OM+SAJvJ umkpLjB1HZo2Hly6LnfPeTtoDhEK1w/Clc8iMkeRm61hmuwqPgNIe7neN91pyx+BO9+E MReoIAtvVklaUf/KHJBkIZfoDB1ybE9+eZWpI= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; b=BqiK2xsH5PVxZEmdz5304zNDpicVp/XEnLFyihHKtQzEtOt7ms7VxDs7z8KN/88vLJ HsH8TNUYXTLzfd4oXkCQY6jl6JoGIee7SkFHEKweOcppMRIHIbJ2FXKo+rPpQdwxeV/F tncQWQl9ZKa2mSjvbbqjpbzhorqhODN3Crp/k= MIME-Version: 1.0 Received: by 10.231.184.75 with SMTP id cj11mr9666763ibb.51.1274904898052; Wed, 26 May 2010 13:14:58 -0700 (PDT) Received: by 10.231.149.5 with HTTP; Wed, 26 May 2010 13:14:57 -0700 (PDT) In-Reply-To: References: <4BF34C9E.3010108@oracle.com> <4BF6E603.9010308@oracle.com> <4BF6E8F1.7010206@oracle.com> <4BFBE1E2.2060903@oracle.com> Date: Wed, 26 May 2010 16:14:57 -0400 Message-ID: Subject: Re: [jsr-314-open] Fwd: PostAddToViewEvent publishing conditions From: Andy Schwartz To: MyFaces Development Cc: jsr-314-open@jcp.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Gang - I attempted to send this earlier today from my work account but it didn't seem to make it through. Re-sending from gmail (with one minor correction). Hopefully I'll have better luck this time. :-) (Apologies if we end up with multiple copies of this...) On 5/26/10 1:27 AM, Martin Marinschek wrote: > Hi Andy, > > my 2cents (isn=B4t worth much in this discussion if I don=B4t look any > deeper into this ;) > > >> Given that ui:decorate is a non-trimming ui:composition, why would these >> behave differently with respect to interaction with the TemplateClient? = I >> would think that both of these handlers should be calling pushClient(). >> > > I don=B4t see why ui:decorate should be different from ui:composition, ei= ther. > Unless someone understands why the implementation is inconsistent across these two cases, I think that we should align the implementations. Note that given the bug that Max logged (against Mojarra): https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=3D1684 I believe that DecorateHandler has got this one right (ie. both DecorateHandler and CompositionHandler should be calling pushClient()). >> Also, the multi-level search strategy seems somewhat questionable to me.= A >> template exposes a certain number of of names into which content could b= e >> inserted. The consumer of the template leverages that contract and >> specifies content to be inserted into some subset of those names. When >> attempting to locate content to insert, why should the template look any >> further up the stack than the nearest consumer (ie. the most recently pu= shed >> TemplateClient)? >> > > > Well, templates are certainly hierarchical - does the nearest consumer > carry all information, or just the one which is defined in itself? > My take on this is that templates are reusable objects with a specific contract (much like composite components, or, well, any component for that matter). The contract is that the template exposes certain slots that users of the template can fill in with their own content. The names of the slots are defined via ui:insert tags in the template implementation. Yeah, I know, you already know this. :-) If the template itself happens to depend on yet another template, I view that as an implementation detail of the template. So, if we've got this situation: - view.xhtml, which includes: - outerTemplate.xhtml, which includes: - innerTemplate.xhtml In my ideal world (which, at the moment, does not match reality), view.xhtml should only be aware of the slots that are exposed by outerTemplate.xhtml. That is, view.xhtml should not depend on the fact that outerTemplate.xhtml happens to include innerTemplate.xhtml, which may have its own slots. The reality is that when nesting templates, the outermost template exposes *all* of the slots defined by any nested templates (no matter how many levels deep) to the consumer. This seems like a violation of encapsulation to me. We are exposing implementation details up through the template hierarchy that, I think, should not necessarily be exposed. Of course, I understand that it may be useful to be able to pass content from view.xhtml all the way through to a slot defined by innerTemplate.xhtml. If outerTemplate.xhtml wants to allow certain content to be passed through from view.xhtml to innerTemplate.xthml, that's fine. However, this should be done by introducing a ui:insert inside of outerTemplate.xhtml - ie. by explicitly exposing a new slot that consumers of outerTemplate.xhtml can rely on. That way, if the author of outerTemplate.xhtml reconsiders the implementation and decides not to delegate to innerTemplate.xhtml after all, users of outerTemplate.xhtml are not hosed. Oh well, this looks like another cases where I am many years too late. That seems to be my fate these days. Even if we cannot change this behavior for ui:insert now, I do think it is important that we avoid this behavior for composite components. Since we are tinkering with the composite:inertFacet/composite:insertChildren implementations now to be more Facelets/TemplateClient-like, let's just be careful to avoid introducing the Facelets nested insert behavior into composite components. >> Right, so I see that InsertHandler is implemented this way, but... why? >> Seems silly to have ui:insert serve two entirely different purposes - i= e. >> to both identify an insertion point as well as to define content for >> included templates. Why should ui:insert act both as a ui:insert *and*= as >> a ui:define? If a template author wants to pass content through from a= n >> outer page to an inner/nested template, seems like the right way to >> accomplish this would be to wrap the ui:insert inside of a ui:define. >> > > Well, if you define a template, you use ui:insert to mark the spots > where content can be - and then you include default content right > away. Is it this which makes ui:insert a thing of both worlds? > Let's take a step back and look at the role of the TemplateClient contract. TemplateClient allows consumers of templates (eg. ui:composition) to provide access to content that should be inserted into the template - ie. content defined by ui:define, inserted into ui:insert. So, for example, both CompositionHandler and DecorateHandler are TemplateClients. ui:insert is clearly a user of the TemplateClient interface. InsertHandler (via a call to FaceletContext.includeDefinition()) pulls in content provided by outer TemplateClients (eg. an ancestor ui:composition). This is all well and good. Where things get strange is that InsertHandler also implements TemplateClient. This means that, in addition to being a consumer of TemplateClient content, ui:insert also exposes its own content for consumption by other consumers of TemplateClients. So, if you've got: body content The "body content" serves two roles: 1. It provides default content in the event that no matching ui:define for "foo" can be found. 2. It is exposed as content for consumption while performing the definition inclusion (during the call to FaceletContext.includeDefinition()). Case #1 is expected/documented. Case #2 is where ui:insert seems to acting as a ui:define. This is non-obvious, and, as far as I can tell, not documented. To me this looks like an old implementation quirk that we have inherited. Does someone here happen to understand why this is useful? If this is useful, we need to document this behavior. If it isn't useful, we should remove this part of the implementation. Andy > best regards, > > Martin > >