Hi

Doing some tests about facelets template client api, I found some examples that requires to take into account a new concept about how templates should be resolved.

The problem was reported on:

http://issues.apache.org/jira/browse/MYFACES-2753

and on:

https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1708

It was closed this issue as duplicate:

https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1684

but really it describes another different problem (in my opinion this issue is invalid but that's another discussion).

In resume, some tags should "isolate" the context where the templates definitions or insertions are resolved. Let's see just two examples (only the important points):

EXAMPLE 1: Composite component

testCompositeInsertChildren4Template.xhtml

<ui:composition>
<h:panelGroup id="testGroup1">
    <h:outputText value="ALFA " />
    <ui:insert name="item">
        <!-- This one should not be rendered -->
        <h:outputText value="EPSILON "/>
    </ui:insert>
    <h:outputText value="OMEGA " />
</h:panelGroup>
</ui:composition>

testCompositeInsertChildren4.xhtml

<ui:composition template="testCompositeInsertChildren4Template.xhtml">
    <ui:define name="item">
        <testComposite:compositeInsertChildren4>
            <h:outputText value="BETA " />
        </testComposite:compositeInsertChildren4>
    </ui:define>
</ui:composition>

compositeInsertChildren4.xhtml

<composite:interface>
</composite:interface>
<composite:implementation>
   <ui:insert name="item">
       <composite:insertChildren/>
   </ui:insert>
   <h:outputText value="GAMMA "/>
</composite:implementation>

Result:

ALFA
BETA
GAMMA
OMEGA

Comments: The tag ui:insert inside composite:implementation should not take into account definitions made "outside" it.

EXAMPLE 2: ui:include

OuterTemplate.xhtml:
<ui:composition>
        <ui:insert name="content" />
</ui:composition>

OuterClient.xhtml
<ui:decorate template="/templates/OuterTemplate.xhtml">
    <ui:define name="content">
        <ui:include src="InnerClient.xhtml" />
    </ui:define>
</ui:decorate>

InnerClient.xhtml:
<ui:composition
    template="/templates/InnerTemplate.xhtml">
    <ui:define name="content">
        Do you see me?
    </ui:define>
</ui:composition>

InnerTemplate.xhtml:
<ui:composition>
    <ui:insert name="content" />
</ui:composition>

Comments: definitions inside ui:include referenced page should ignore what is outside it.

As you can see, there are some situations where the tag semantic requires isolate the context where the templates are resolved. After do some test I identified these cases:

- Composite components
- ui:include
- User tag handlers (facelets tags from xhtml files)

The solution implemented on myfaces is use a class called TemplateContext, that encapsulates template operations, and use a stack to isolate the different context. When a new context is required a new TemplateContextImpl is created and pushed on the stack. When it is no longer required it is removed from the stack. If it is necessary to resolve the  markup on the previous context, we temporally pop the context from the stack and the push it again. It passes all tests proposed.

I'm still thinking about how template client api should be to write a proposal about it, but I wanted to comment this stuff because it could be of interest here.

Suggestions are welcome,

best regards,

Leonardo Uribe