Include sub-element inside JSF 2.0 component
Asked Answered
G

2

10

This must be simple. I am trying to pass sub-element into a JSF component. I have my component declared as:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:composite="http://java.sun.com/jsf/composite">

<composite:interface>
</composite:interface>

<composite:implementation>
    <div style="border: 1px solid black;">
        <ui:insert />
    </div>
</composite:implementation>

</html>

Then I use this in a page by:

<box:box>
    <p>Hello world!</p>
</box:box>

Unfortunately, the box renders ok (the black border) but the "Hello world!" text is not included within it. I also tried more verbose syntax by using <ui:insert name="content"> and calling by <ui:define name="content">Hello World!</ui:define> but it didn't work.

Where might I be making a mistake?

Guenna answered 13/8, 2010 at 7:22 Comment(0)
G
13

Ok I figured it out. You should use <composite:insertChildren /> instead as in:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:composite="http://java.sun.com/jsf/composite">

<composite:interface>
</composite:interface>

<composite:implementation>
    <div style="border: 1px solid black;">
        <composite:insertChildren />
    </div>
</composite:implementation>

</html>

This works.

Guenna answered 13/8, 2010 at 11:33 Comment(0)
P
0

You have to send the content as parameter:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

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

    <composite:interface>
         <composite:attribute name="content"/>
    </composite:interface>

    <composite:implementation>
        <div style="border: 1px solid black;">
             <h:outputText value="#{cc.attrs.content}" escape="false"/>
        </div>
    </composite:implementation>

</html>

and in your code:

<box:box content="<p>Hello world!</p>" />

I added the escape="false" since you are using HTML tags inside the EL expression.

Read more about composite elements in David Geary’s article

Pantelegraph answered 13/8, 2010 at 8:11 Comment(1)
Yes this would be one way to do that but it's very ugly design. Also, what if I have a longer section of XHTML/JSF code that I want to use as sub-element? Passing the content as string attribute is unconvenient. Instead, the style I tried (using <ui:insert />) should work, as lined in packtpub.com/article/creating-composition-components-in-jsf-2.0 (look at the chapter "Passing sub-elements to composition components"). This same approach is also covered in book JSF 2 APIs and JBoss Seam. However, in my tests it fails.Guenna

© 2022 - 2024 — McMap. All rights reserved.