Nested template overwrite ui:default with ui:insert
Asked Answered
E

1

6

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.

Enrollee answered 26/12, 2012 at 6:15 Comment(0)
A
11

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.

Adulterous answered 26/12, 2012 at 9:15 Comment(2)
I'd love that feature too! I guess the new link is this one: github.com/javaee/javaserverfaces-spec/issues/1008Valentijn
@ASE Thx, I updated the post. I'm basically now in the position to add this myself to JSF, however since there's currently no active EG and a transfer to the Eclipse foundation is in-progress I have to see how to exactly proceed with that.Adulterous

© 2022 - 2024 — McMap. All rights reserved.