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

djm*_*jmj 5 jsf templates 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>
Run Code Online (Sandbox Code Playgroud)

模板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>
Run Code Online (Sandbox Code Playgroud)

网站1:

<ui:composition template="/resources/templates/B.xhtml">
    Site 1<br/>
    <ui:define name="content">
        site content<br/>
    </ui:define>
</ui:composition>
Run Code Online (Sandbox Code Playgroud)

输出:

Site 1
site content
Run Code Online (Sandbox Code Playgroud)

该内容<ui:define>取自站点1,不会呈现模板的内容.

网站2:

<ui:composition template="/resources/templates/B.xhtml">
    Site 2<br/>
</ui:composition>
Run Code Online (Sandbox Code Playgroud)

输出:

Site 2
template B content
template A content
Run Code Online (Sandbox Code Playgroud)

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

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

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

Arj*_*jms 10

不幸的是,Facelets不允许你"链接"插入/定义.

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

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

template A content
site content
Run Code Online (Sandbox Code Playgroud)

即"模板A内容"位于insert标签之外的最低模板中.它将直接呈现."网站内容"位于definition"内容" 的最顶层.

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

template A content
template B content
Run Code Online (Sandbox Code Playgroud)

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

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

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

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