[ 
https://issues.apache.org/jira/browse/MYFACES-2753?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12887461#action_12887461
 ] 

Jakob Korherr commented on MYFACES-2753:
----------------------------------------

I added a patch with some JUnit test cases to be able to test this templating 
stuff better. It includes some general templating tests and also the (slightly 
modified) example from     Martin Kočí.

Furthermore I added a patch that solves this issue. I will try to explain the 
problem and the actions taken in the patch:

The problem was that CompositionHandler used extendClient(this) instead of 
pushClient(this), thus the <ui:composition> was added at the end of the 
TemplateClient stack and thus the default values (= body of <ui:insert> tags) 
were applied instead of the real values, and because of the fact that 
<ui:insert> was used without a body in the example, nothing was inserted. This 
is a very weird problem, because all other similar facelets tags (e.g. 
<ui:decorate>) have mostly the same functionality, but use pushClient(this). 
Thus the above example works well without any patch just by using <ui:decorate> 
instead of <ui:composition> on the innerClient.

Digging into the problem I found out that this code was not changed since we 
integrated faceletes into our codebase, thus I searched the faceletes codebase. 
There I found the following commit from 2006-03-10, luckily without a commit 
message...
https://facelets.dev.java.net/source/browse/facelets/src/java/com/sun/facelets/tag/ui/CompositionHandler.java?r1=1.9&r2=1.9.4.1

Actually this commit does not make any sence to me and by "reverting" it on our 
codebase, the above example works fine.

However, after digging more and more into the facelets templating code, I found 
out that extendClient() and popExtendedClient() do not make any sence at all. 
Those two methods are only used by InsertHandler to provide the "fallback" 
mechanism if a <ui:insert> does not find the corresponding <ui:define>. For 
this scenario the InsertHandler itself is added at the end of the 
TemplateClient stack. But afterwards, when going through the stack, those 
handlers are never applied, because they will never pass the 
if(client.equals(owner)) on TemplateContextImpl. Furthermore this would lead to 
a wrong order of default values in a multi-level templating scenario. However 
the current code does provide these default values and by looking at the code 
of InsertHandler.apply() this is very clear why:

// apply the nearest matching <ui:define> in the template hierarchy
boolean found = actx.includeDefinition(parent, this.name);
if (!found)
{
    // if no definition found, apply a fallback definition
    // (= body of this <ui:insert>)
    this.nextHandler.apply(ctx, parent);
}

Thus the patch includes the following actions:
 - use pushClient() instead of extendClient() and popClient() instead of 
popExtendedClient() in CompositionHandler
 - remove extendClient() and popExtendedClient(), because they are just wrong
 - remove TemplateClient code from InsertHandler
 - rename _handlers to _defineHandlers for clarity
 - add some comments for clarity

If there are no objections, I will commit both patches soon.

> Trivial multi-level templating does not work if ui:include is used
> ------------------------------------------------------------------
>
>                 Key: MYFACES-2753
>                 URL: https://issues.apache.org/jira/browse/MYFACES-2753
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: JSR-314
>    Affects Versions: 2.0.2-SNAPSHOT
>         Environment: myfaces core trunk (2.0.2-SNAPSHOT), tomcat 6.0.26
>            Reporter: Martin Kočí
>            Assignee: Jakob Korherr
>         Attachments: MYFACES-2753-tests.patch, MYFACES-2753.patch, 
> MYFACES-2753.tar.gz
>
>
> Following example does not produce any output:
> OuterClient.xhtml
> <ui:decorate
>     template="/templates/OuterTemplate.xhtml"
>     xmlns:ui="http://java.sun.com/jsf/facelets";>
>     <ui:define name="content">
>         <ui:include src="InnerClient.xhtml" />
>     </ui:define>
> </ui:decorate>
> OuterTemplate.xhtml:
> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
> "http://www.w3.org/TR/html4/loose.dtd";>
> <html
>     xmlns="http://www.w3.org/1999/xhtml";
>     xmlns:ui="http://java.sun.com/jsf/facelets";
>     xmlns:f="http://java.sun.com/jsf/core";
>     xmlns:h="http://java.sun.com/jsf/html";>
> <f:view>
>     <h:head>
>         <title>title</title>
>     </h:head>
>     <h:body>
>         <ui:insert name="content" />
>     </h:body>
> </f:view>
> </html>
> InnerClient.xhtml:
> <ui:composition
>     template="/templates/InnerTemplate.xhtml"
>     xmlns="http://www.w3.org/1999/xhtml";
>     xmlns:ui="http://java.sun.com/jsf/facelets";>
>     <ui:define name="content">
>         Do you see me?
>     </ui:define>
> </ui:composition>
> InnerTemplate.xhtml:
> <f:subview
>     xmlns:ui="http://java.sun.com/jsf/facelets";
>     xmlns:f="http://java.sun.com/jsf/core";>
>     <ui:insert name="content" />
> </f:subview>
> But if OutterClient.xhtml looks like:
> <ui:decorate
>     template="/templates/OuterTemplate.xhtml"
>     xmlns:ui="http://java.sun.com/jsf/facelets";>
>     <ui:define name="content">
>         <ui:composition template="/templates/InnerTemplate.xhtml">
>             <ui:define name="content">
>                 Do you see me?
>             </ui:define>
>         </ui:composition>
>     </ui:define>
> </ui:decorate>
> it outputs "Do you see me?" which is expected result in both cases. I think 
> first case should work too - or am I missing something?

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to