Problem using include in Facelets

Shervin Asgari picture Shervin Asgari · Nov 5, 2010 · Viewed 10.3k times · Source

I have problems including a facelet template. I wanted to split some content up, so that I can reuse it somewhere else.

So I changed this code:

<!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>

To this:

<!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>

And inside admin-generic.xhtml I wrapped the code in a 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>

But nothing is shown. I just get a blank page, with no errors. Is it wrong using ui:composition? I have tried with ui:component but that didn't help either.


Update: According to my Facelets Essentials Guide, it says:

The ui:include tag can be used to include another Facelets file into your document. It simply includes whatever source file you specify. You can include any Facelets file that has ui:component or ui:composition tags (which trim the content outside themselves) or simply a fragment of XHTML or XML.

Is that what is going on? Is the content outside of the include trimmed away? How can I just include the page, without the content outside being trimmed?

Answer

BalusC picture BalusC · Nov 8, 2010

The <ui:define> has to be placed in an <ui:composition> or <ui:decorate> with a template containing the appropriate <ui:insert> tags. You've moved it to an <ui:composition> without a template. No template means no content.

Technically, to achieve your requirement, you have to replace the <ui:include> by <ui:insert>.

<!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>

And declare the above page (I assume it as somepage.xhtml) as template in admin_generic.xhtml.

<!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>

Note that you have to open admin_generic.xhtml in the browser instead. If your intent is to open somepage.xhtml in browser, then the <ui:define> really has to stay in somepage.xhtml. You can however replace the body of <ui:define> by a simple <ui:include>.

<!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>

It allows for <ui:composition>, so you don't necessarily need to put the <table> to 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>