如何在一个XHTML页面中正确地包含另一个XHTML页面?我已经尝试了不同的方法,但都没有成功。
<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
(是的,这就是文件的全部内容,任何在<ui:composition>
之外的标签都是不必要的,因为它们无论如何都会被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
打开此文件。请注意,您不需要在包含文件中重复使用<html>
、<h:head>
和 <h:body>
标签,因为这样会导致无效的HTML。
您可以在<ui:include src>
中使用动态EL表达式。参见如何通过导航菜单进行ajax刷新动态包含内容?(JSF SPA).
<ui:define>
/<ui:insert>
一种更高级的包含方式是“模板”。这基本上是另一种方式。主模板页面应使用<ui:insert>
声明插入已定义模板内容的位置。使用主模板页面的模板客户端页面应使用<ui:define>
定义要插入的模板内容。
主模板页面/WEB-INF/template.xhtml
(作为设计提示:标题、菜单和页脚甚至可以是<ui:include>
文件):
<!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
打开。如果没有<ui:define>
,则将显示<ui:insert>
中的默认内容(如果有)。
<ui:param>
您可以使用<ui:param>
向<ui:include>
或<ui:composition template>
传递参数。
<ui:include ...>
<ui:param name="foo" value="#{bean.foo}" />
</ui:include>
<ui:composition template="...">
<ui:param name="foo" value="#{bean.foo}" />
...
</ui:composition >
在include/template文件中,你可以使用#{foo}
进行引用。如果需要向<ui:include>
传递多个参数,则最好将include文件注册为标签文件,这样你最终可以像这样使用它:<my:tagname foo="#{bean.foo}">
。参见When to use <ui:include>, tag files, composite components and/or custom components?
你甚至可以通过<ui:param>
传递整个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?
<ui:composition>
和<ui:define>
之外不需要任何标记(HTML代码)。你可以放置任何标记,但是它们将被Facelets 忽略。放置标记只对网页设计师有用。参见Is there a way to run a JSF page without building the whole project?
HTML5 doctype是目前推荐使用的doctype,尽管它是一个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源代码的src/main/webapp文件夹和OmniFaces演示站点源代码。
包含的页面:
<!-- 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
引入该文件。<ui:include src="/yourFile.xhtml"/>
或者 <ui:include src="/WEB-INF/yourFile.xhtml"/>
。 - Oleksa O.
<ui:composition ...>
,则必须像这样声明doctype:<!DOCTYPE html PUBLIC "-// W3C // DTD XHTML 1.0 Transitional // EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
,否则使用HTML实体时会出现"entity referenced but not declared"错误。 - ChristophS