Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested template overwrite ui:default with ui:insert

Is there a rule on how to overwrite template definitions <ui:define> with <ui:insert>.

Template A:

<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets">
    template A content<br/>
    <ui:insert name="content"/>
</ui:composition>

Template B:

<ui:composition template="/resources/templates/A.xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets">
    <ui:define name="content">
        template B content<br/>
        <ui:insert name="content"/>
    </ui:define>
</ui:composition>

Site 1:

<ui:composition template="/resources/templates/B.xhtml">
    Site 1<br/>
    <ui:define name="content">
        site content<br/>
    </ui:define>
</ui:composition>

Output:

Site 1
site content

Content for the <ui:define> is taken from Site 1, the content of the templates is not rendered.

Site 2:

<ui:composition template="/resources/templates/B.xhtml">
    Site 2<br/>
</ui:composition>

Output:

Site 2
template B content
template A content

Content for the <ui:define> is taken from template B and template A, where strangely template B content is rendered before content of template A.

Is it possible to overwrite <ui:define> with a new <ui:insert> using same name?

Creating new names for the nested <ui:insert> is one possibility but its hard to keep track of the hierarchy and where insert's are used at all.

like image 360
djmj Avatar asked Dec 26 '12 06:12

djmj


1 Answers

Unfortunately Facelets doesn't allow you to 'chain' insert/define.

In your first example (Site 1), there is single insert in Template A called "content". There are two definitions being considered; that of the direct template client (Template B) and that of the template client of Template B (Site 1). For this case, Facelets does not see that Template B has another insert. It just considers two competing definitions for "content", and the rule is that the top-most one wins, which is Site 1.

You did forgot to put the namespace on the template client though. The output you should be seeing is:

template A content
site content

Namely "template A content" is in the lowest template, outside the insert tag. It will be rendered directly. "site content" is in the top-most definition of "content".

In the second example (Site 2), there is no definition at all in the top-most template client. There is only one definition, and that's in Template B, so that one will be used. The output you should be seeing is:

template A content
template B content

You'll see "template A content" for the same reasons as in the first example, and "template B content" since it's the only definition. The nested second insert after that will be ignored.

Creating new names for the nested is one possibility but its hard to keep track of the hierarchy and where insert's are used at all.

It is indeed. Precisely for this reason I created a spec issue over a year ago for this at: https://github.com/eclipse-ee4j/faces-api/issues/1008

If this particular functionality is important to you please vote and/or leave a comment.

like image 139
Arjan Tijms Avatar answered Nov 15 '22 10:11

Arjan Tijms