嵌套模板覆盖ui:默认为ui:insert

时间:2012-12-26 06:15:32

标签: templates jsf facelets

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

模板A:

<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>的内容来自网站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>创建新名称是一种可能性,但很难跟踪层次结构以及插件的使用位置。

1 个答案:

答案 0 :(得分:10)

不幸的是,Facelets不允许你“链接”插入/定义。

在您的第一个示例(网站1 )中,模板A中有一个名为“内容”的单insert。有两个definitions被考虑;直接模板客户端(模板B)和模板B(站点1)的模板客户端的模板。对于这种情况,Facelets看不到模板B有另一个insert。它只考虑两个竞争definitions的“内容”,规则是最顶层的一个获胜,即网站1。

您确实忘了将命名空间放在模板客户端上。您应该看到的输出是:

template A content
site content

即“模板A内容”位于insert标记之外的最低模板中。它将直接呈现。 “网站内容”位于“内容”的最顶层definition

在第二个示例(站点2 )中,最顶层的模板客户端中根本没有definition。只有一个definition,并且在模板B中,因此将使用一个template A content template B content 。您应该看到的输出是:

definition

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

  

为嵌套创建新名称是一种可能性,但很难跟踪层次结构以及插件的使用位置。

确实如此。正是因为这个原因,我在一年前创建了一个规范问题:https://github.com/javaee/javaserverfaces-spec/issues/1008

如果此特定功能对您很重要,请投票和/或发表评论。