在 Facelets 中使用包含的问题

Posted

技术标签:

【中文标题】在 Facelets 中使用包含的问题【英文标题】:Problem using include in Facelets 【发布时间】:2011-05-05 14:41:37 【问题描述】:

我遇到了包含 facelet 模板的问题。我想拆分一些内容,以便在其他地方重复使用。

所以我更改了这段代码:

<!DOCTYPE html>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    template="/layout/template.xhtml">

    <ui:define name="head">
        <title>Title</title>
    </ui:define>

    <ui:define name="header">
        <h3>Header</h3>
    </ui:define>

    <ui:define name="content">
        <table><tr><td>table</td></tr></table>
    </ui:define>
</ui:composition>

到这里:

<!DOCTYPE html>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    template="/layout/template.xhtml">

    <ui:define name="head">
        <title>Title</title>
    </ui:define>

    <ui:include src="/admin/admin_generic.xhtml"/>
</ui:composition>

admin-generic.xhtml 中,我将代码封装在 ui:composition 中。

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets">

    <ui:define name="header">
        <h3>Header</h3>
    </ui:define>

    <ui:define name="content">
        <table><tr><td>table</td></tr></table>
    </ui:define>
</ui:composition>

但是什么也没显示。我只是得到一个空白页,没有错误。使用ui:composition 有错吗?我曾尝试使用ui:component,但这也无济于事。


更新:根据我的 Facelets Essentials Guide,它说:

ui:include 标签可用于将另一个 Facelets 文件包含到您的 文档。它只包含您指定的任何源文件。你可以 包括任何具有 ui:componentui:composition 标记的 Facelets 文件 (将内容修剪到自己之外) 或只是一个片段 XHTML 或 XML。

这是怎么回事?包含之外的内容是否被修剪掉了?我怎样才能只包含页面,而不修剪外面的内容?

【问题讨论】:

【参考方案1】:

&lt;ui:define&gt; 必须放在&lt;ui:composition&gt;&lt;ui:decorate&gt; 包含适当&lt;ui:insert&gt; 标记的template 中。您已将其移至 &lt;ui:composition&gt; 没有 template。没有模板就没有内容。

从技术上讲,要满足您的要求,您必须将 &lt;ui:include&gt; 替换为 &lt;ui:insert&gt;

<!DOCTYPE html>
<ui:composition
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    template="template.xhtml">

    <ui:define name="head">
        <title>Title</title>
    </ui:define>

    <ui:insert />
</ui:composition>

并在admin_generic.xhtml 中将上述页面(我假设为somepage.xhtml)声明为template

<!DOCTYPE html>
<ui:composition
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    template="somepage.xhtml">

    <ui:define name="header">
        <h1>Header</h1>
    </ui:define>

    <ui:define name="content">
        <table><tr><td>table</td></tr></table>
    </ui:define>
</ui:composition>

请注意,您必须改为在浏览器中打开 admin_generic.xhtml。如果您的意图是在浏览器中打开somepage.xhtml,那么&lt;ui:define&gt; 确实必须留在somepage.xhtml 中。但是,您可以将&lt;ui:define&gt; 的主体替换为简单的&lt;ui:include&gt;

<!DOCTYPE html>
<ui:composition 
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    template="template.xhtml">

    <ui:define name="head">
        <title>Title</title>
    </ui:define>

    <ui:define name="header">
        <h1>Header</h1>
    </ui:define>

    <ui:define name="content">
        <ui:include src="admin_generic.xhtml" />
    </ui:define>
</ui:composition>

它允许&lt;ui:composition&gt;,因此您不一定需要将&lt;table&gt; 设置为root。

<!DOCTYPE html>
<ui:composition 
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets">

    <table><tr><td>table</td></tr></table>
</ui:composition>

【讨论】:

不客气。将来尽量减少问题中不相关的噪音,以便其他人更快地回答:)【参考方案2】:

我通过删除&lt;ui:composition&gt;&lt;ui:define&gt; 并直接在&lt;table&gt; 中添加命名空间来解决这个问题,如下所示:

<table class="adminform" xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a="http://richfaces.org/a4j">

所以现在我的页面是这样的:

<ui:define name="content">
    <ui:include src="/admin/admin_generic.xhtml" />
</ui:define>

【讨论】:

您不一定需要将表声明为root。 ui:composition 也可以。我认为您的误解是由大量试错引起的。重点是ui:define 必须与ui:compositiontemplate 一起使用。

以上是关于在 Facelets 中使用包含的问题的主要内容,如果未能解决你的问题,请参考以下文章

JSF 2:如何将包含要调用的参数的动作传递给 Facelets 子视图(使用 ui:include 和 ui:param)?

将静态 HTML(无效 XHTML)文件包含到 JSF Facelets

Facelets:页面未呈现

如何创建自定义 Facelets 标签?

在 Facelets 中使用 JavaScript 时出现 XHTML 解析错误 [重复]

如何在 Facelets 的 EL 布尔表达式中使用 &&?