【问题标题】:How to include another XHTML in XHTML using JSF 2.0 Facelets?如何使用 JSF 2.0 Facelets 在 XHTML 中包含另一个 XHTML?
【发布时间】:2015-10-19 01:58:18
【问题描述】:

在 XHTML 页面中包含另一个 XHTML 页面的最正确方法是什么?我一直在尝试不同的方法,它们都不起作用。

【问题讨论】:

    标签: jsf xhtml include jsf-2 facelets


    【解决方案1】:

    <ui:include>

    最基本的方式是<ui:include>。包含的内容必须放在<ui:composition>内。

    母版页的启动示例/page.xhtml

    <!DOCTYPE html>
    <html lang="en"
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://xmlns.jcp.org/jsf/core"
        xmlns:h="http://xmlns.jcp.org/jsf/html"
        xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
        <h:head>
            <title>Include demo</title>
        </h:head>
        <h:body>
            <h1>Master page</h1>
            <p>Master page blah blah lorem ipsum</p>
            <ui:include src="/WEB-INF/include.xhtml" />
        </h:body>
    </html>
    

    包含页面/WEB-INF/include.xhtml(是的,这是整个文件,&lt;ui:composition&gt; 之外的任何标签都是不必要的,因为它们无论如何都会被 Facelets 忽略):

    <ui:composition 
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://xmlns.jcp.org/jsf/core"
        xmlns:h="http://xmlns.jcp.org/jsf/html"
        xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
        <h2>Include page</h2>
        <p>Include page blah blah lorem ipsum</p>
    </ui:composition>
      
    

    这需要/page.xhtml打开。请注意,您不需要在包含文件中重复 &lt;html&gt;&lt;h:head&gt;&lt;h:body&gt;,否则会导致 invalid HTML

    您可以在&lt;ui:include src&gt; 中使用动态EL 表达式。另见How to ajax-refresh dynamic include content by navigation menu? (JSF SPA)


    &lt;ui:define&gt;/&lt;ui:insert&gt;

    一种更高级的包含方法是模板化。这基本上包括相反的方式。主模板页面应使用&lt;ui:insert&gt; 声明插入已定义模板内容的位置。使用主模板页面的模板客户端页面应使用&lt;ui:define&gt;定义要插入的模板内容。

    主模板页面/WEB-INF/template.xhtml(作为设计提示:页眉、菜单和页脚甚至可以是&lt;ui:include&gt;文件):

    <!DOCTYPE html>
    <html lang="en"
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://xmlns.jcp.org/jsf/core"
        xmlns:h="http://xmlns.jcp.org/jsf/html"
        xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
        <h:head>
            <title><ui:insert name="title">Default title</ui:insert></title>
        </h:head>
        <h:body>
            <div id="header">Header</div>
            <div id="menu">Menu</div>
            <div id="content"><ui:insert name="content">Default content</ui:insert></div>
            <div id="footer">Footer</div>
        </h:body>
    </html>
    

    模板客户端页面/page.xhtml(注意template 属性;同样在这里,这是整个文件):

    <ui:composition template="/WEB-INF/template.xhtml"
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://xmlns.jcp.org/jsf/core"
        xmlns:h="http://xmlns.jcp.org/jsf/html"
        xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
    
        <ui:define name="title">
            New page title here
        </ui:define>
    
        <ui:define name="content">
            <h1>New content here</h1>
            <p>Blah blah</p>
        </ui:define>
    </ui:composition>
    

    这需要/page.xhtml打开。如果没有&lt;ui:define&gt;,则显示&lt;ui:insert&gt;中的默认内容,如果有的话。


    &lt;ui:param&gt;

    您可以通过&lt;ui:param&gt;将参数传递给&lt;ui:include&gt;&lt;ui:composition template&gt;

    <ui:include ...>
        <ui:param name="foo" value="#{bean.foo}" />
    </ui:include>
    
    <ui:composition template="...">
        <ui:param name="foo" value="#{bean.foo}" />
        ...
    </ui:composition >
    

    在包含/模板文件中,它将以#{foo} 的形式提供。如果您需要将“许多”参数传递给&lt;ui:include&gt;,那么您最好考虑将包含文件注册为标记文件,以便您最终可以像&lt;my:tagname foo="#{bean.foo}"&gt;那样使用它。另见When to use <ui:include>, tag files, composite components and/or custom components?

    您甚至可以通过&lt;ui:param&gt; 传递整个bean、方法和参数。另见JSF 2: how to pass an action including an argument to be invoked to a Facelets sub view (using ui:include and ui:param)?


    设计提示

    不应仅通过输入/猜测其 URL 即可公开访问的文件需要放置在 /WEB-INF 文件夹中,如上例中的包含文件和模板文件。另见Which XHTML files do I need to put in /WEB-INF and which not?

    &lt;ui:composition&gt;&lt;ui:define&gt; 之外不需要任何标记(HTML 代码)。您可以放置​​任何内容,但它们会被 Facelets忽略。把标记放在那里只对网页设计师有用。另见Is there a way to run a JSF page without building the whole project?

    HTML5 文档类型是当今推荐的文档类型,“尽管”它是一个 XHTML 文件。您应该将 XHTML 视为一种允许您使用基于 XML 的工具生成 HTML 输出的语言。另见Is it possible to use JSF+Facelets with HTML 4/5?JavaServer Faces 2.2 and HTML5 support, why is XHTML still being used

    CSS/JS/image 文件可以作为动态可重定位/本地化/版本化资源包含在内。另见How to reference CSS / JS / image resource in Facelets template?

    您可以将 Facelets 文件放入可重用的 JAR 文件中。另见Structure for multiple JSF projects with shared code

    有关高级 Facelets 模板的真实示例,请查看 Java EE Kickoff App source codeOmniFaces showcase site source codesrc/main/webapp 文件夹。

    【讨论】:

    • 嗨 Balus,关于:最基本的方法是 。包含的内容必须放在 中。我认为包含的内容可以简单地放在

      中它会起作用。
    • @KorayTugay:是的,没错。 ui:composition 只需要 a) 使用模板(见上文),或 b) 将所有内容包装在 中,以便您可以使用浏览器或 HTML 编辑器加载文件。
    • 嗨,你能帮我解开这个谜吗?从过去的 3 天开始,我一直在敲我的头。 stackoverflow.com/questions/24738079/…
    • @Odysseus:如果它实际上是一个作品,则不是。
    • Afaik 如果只在 facelet 中声明 &lt;ui:composition ...&gt;,您还必须声明像 &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; 这样的文档类型,否则在使用 HTML 实体时会出现 entity referenced but not declared 错误。
    【解决方案2】:

    收录页面:

    <!-- opening and closing tags of included page -->
    <ui:composition ...>
    </ui:composition>
    

    包含页面:

    <!--the inclusion line in the including page with the content-->
    <ui:include src="yourFile.xhtml"/>
    
    • 您以ui:composition 开头包含的xhtml 文件,如上所示。
    • 您将带有ui:include 的文件包含在包含xhtml 的文件中,如上所示。

    【讨论】:

    • 有时仅使用文件名来识别路径是不够的。对于那些尝试了上面的文件包含但它不起作用的人。您可以尝试在文件名或 /WEB-INF 目录前添加斜杠符号。所以它看起来像&lt;ui:include src="/yourFile.xhtml"/&gt;&lt;ui:include src="/WEB-INF/yourFile.xhtml"/&gt;
    猜你喜欢
    • 2013-06-07
    • 2014-06-21
    • 1970-01-01
    相关资源
    最近更新 更多