Keywords: JSF | Facelets | XHTML Inclusion | Page Templates | UI Components
Abstract: This technical paper provides an in-depth analysis of XHTML page inclusion mechanisms in JSF 2.0 Facelets framework, focusing on three primary methods: <ui:include>, <ui:define>/<ui:insert> template system, and <ui:param> parameter passing. Through detailed code examples and architectural analysis, it explores usage scenarios, best practices, and common pitfalls for each inclusion approach, enabling developers to build modular and maintainable web applications.
Fundamentals of Facelets Page Inclusion
In JSF 2.0 Facelets framework, page inclusion serves as a core technology for code reuse and modular development. Unlike traditional JSP includes, Facelets offers more flexible and powerful inclusion mechanisms that effectively manage complex web interface structures.
Basic Inclusion with <ui:include>
The <ui:include> tag represents the most straightforward approach to page inclusion, with its primary function being to embed content from specified XHTML files into the current page. This inclusion method is particularly suitable for reusable UI components or content fragments.
Master page example code:
<!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>Inclusion Demo</title>
</h:head>
<h:body>
<h1>Master Page</h1>
<p>Master page content area</p>
<ui:include src="/WEB-INF/include.xhtml" />
</h:body>
</html>
Included page structure:
<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>Included Page Title</h2>
<p>Detailed description of included page content</p>
</ui:composition>
Key design principle: Included files must use <ui:composition> as the root element, with any markup outside this tag being ignored by the Facelets engine. This design ensures valid HTML document structure and prevents validation errors caused by duplicate <html>, <head>, and <body> tags.
Dynamic Inclusion with EL Expressions
The src attribute of the <ui:include> tag supports dynamic EL expressions, enabling inclusion logic to vary based on runtime conditions. For example:
<ui:include src="#{bean.dynamicTemplatePath}" />
This dynamic capability provides strong support for building single-page applications (SPA) and conditional interface rendering, allowing content refresh through Ajax technology.
Template System: <ui:define> and <ui:insert>
The Facelets template system employs a reverse inclusion design philosophy, where master template pages define insertable regions that client pages populate with specific content. This approach is particularly suitable for building web applications with unified layouts.
Master template page example:
<!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">Page Header</div>
<div id="menu">Navigation Menu</div>
<div id="content"><ui:insert name="content">Default Content Area</ui:insert></div>
<div id="footer">Page Footer</div>
</h:body>
</html>
Client page implementation:
<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">
Custom Page Title
</ui:define>
<ui:define name="content">
<h1>Custom Content Title</h1>
<p>Specific page content description</p>
</ui:define>
</ui:composition>
The template system's advantage lies in its default content mechanism, where template default content automatically displays when client pages don't define specific regions, enhancing system robustness.
Parameter Passing with <ui:param>
The <ui:param> tag provides flexible parameter passing mechanisms for page inclusion and template systems, supporting simple values, complex objects, and even method references.
Basic parameter passing example:
<ui:include src="/WEB-INF/included.xhtml">
<ui:param name="userName" value="#{userBean.name}" />
<ui:param name="pageCount" value="10" />
</ui:include>
Template parameter passing:
<ui:composition template="/WEB-INF/template.xhtml">
<ui:param name="configSettings" value="#{appConfig.settings}" />
<ui:define name="content">
<!-- Using passed parameters -->
<p>Configuration Information: #{configSettings}</p>
</ui:define>
</ui:composition>
In included pages or templates, these parameters can be directly accessed through EL expressions like #{userName} or #{configSettings}.
Advanced Design and Best Practices
Secure File Organization: Sensitive or internally used template files should be placed in the /WEB-INF directory, where files cannot be directly accessed via URL, providing an additional security layer.
Markup Processing Principle: Facelets ignores all markup outside <ui:composition> and <ui:define>, enabling designers to maintain page previewability without affecting final rendering results.
Modern Document Types: While using XHTML syntax, HTML5 document type declaration is recommended, reflecting XHTML's nature as an XML tool for generating HTML output.
Resource Management: CSS, JavaScript, and image resources should be managed through JSF's resource mechanism, supporting dynamic relocation, localization, and version control.
Component Reuse Strategy: For complex inclusion scenarios requiring multiple parameters, consider registering included files as tag files to provide clearer and type-safe interfaces.
Architectural Considerations and Performance Optimization
In practical projects, common page fragments (such as headers, footers, navigation menus) can be encapsulated as independent include files, building complex page structures by combining these basic components. This modular approach significantly improves code maintainability and reusability.
Regarding performance, Facelets' inclusion mechanism undergoes compile-time optimization, resulting in efficient rendering performance for generated final pages. For frequently changing dynamic content, Ajax technology can be combined to achieve partial refresh, avoiding complete page reloads.
By appropriately utilizing various Facelets inclusion mechanisms, developers can build web applications with clear structure, easy maintenance, and excellent performance, meeting various requirements of modern web development.