嵌套模板用ui:insert覆盖ui:default



是否有关于如何用<ui:insert>覆盖模板定义<ui:define>的规则?

模板:

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

模板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>

网站1:

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

Site 1
site content

<ui:define>的内容取自Site 1,模板的内容不呈现

网站2:

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

Site 2
template B content
template A content

<ui:define>的内容取自模板B和模板A,奇怪的是,模板B的内容呈现在模板A的内容之前。

是否可以用相同的名称覆盖<ui:define>与新的<ui:insert> ?

为嵌套的<ui:insert>创建新名称是一种可能性,但是很难跟踪层次结构和insert的使用位置

遗憾的是,Facelets不允许您'链式'插入/定义

在您的第一个示例(Site 1)中,模板A中有单个insert称为"content"。目前正在考虑两个definitions;直接模板客户端(模板B)和模板B(站点1)的模板客户端。在这种情况下,Facelets看不到模板B有另一个insert。它只考虑两个竞争的definitions"内容",规则是最上面的一个获胜,即站点1。

但是,您确实忘记了将名称空间放在模板客户机上。您应该看到的输出是:
template A content
site content

即"模板A内容"位于最低的模板中,在insert标签之外。它将被直接渲染。"site content"在"content"最上面的definition

在第二个示例中(Site 2),在最顶层的模板客户端中根本没有definition。只有一个definition,那是在模板B中,所以将使用一个。您应该看到的输出是:

template A content
template B content

您将看到"模板A内容",原因与第一个示例相同,而"模板B内容",因为它是唯一的definition。之后嵌套的第二个insert将被忽略。

为嵌套创建新名称是一种可能性,但是很难跟踪层次结构以及在哪里使用了insert。

确实如此。正是由于这个原因,我在一年前创建了一个规范问题:https://github.com/eclipse-ee4j/faces-api/issues/1008

如果这个功能对你来说很重要,请投票和/或留下评论。

最新更新