Search code examples
jsf-2faceletscomposite-component

How to embed multiple composites (widgets) in a composite container in JSF 2.0?


In JSF 2.0, I want to put multiple widgets into a widget container (that is a div with a title text).

I created the widget container as a composite:

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:a4j="http://richfaces.org/a4j"
    xmlns:rich="http://richfaces.org/rich"
    xmlns:composite="http://java.sun.com/jsf/composite">

<composite:interface name="tileContainer" displayName="Tile container respectively category."
    shortDescription="This tile container may be used to gather multiple different tiles. Caution. Let CSS take care of the layout, the composite the logic.">
    <composite:attribute name="title" default="" required="false"
        type="java.lang.String" />
</composite:interface>

<composite:implementation>
    <div class="tileContainer">
        <div class="title">#{cc.attrs.title}</div>
    </div>
</composite:implementation>
</html>

Here is the widget that needs to be embeded within the tileContainer:

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:a4j="http://richfaces.org/a4j"
    xmlns:rich="http://richfaces.org/rich"
    xmlns:composite="http://java.sun.com/jsf/composite">

<!-- INTERFACE -->
<composite:interface name="pictureTextTile" shortDescription="Provides a top-aligned imaged followed by text.">
    <composite:attribute name="title" default="" required="false"
        type="java.lang.String" />      
    <composite:attribute name="isVerticalStacked" default="true" type="java.lang.Boolean"/>
    <composite:attribute name="picture" required="false"/>
    <composite:attribute name="teaser" required="false" type="java.lang.String"/>
    <composite:attribute name="article" required="true" type="java.lang.String"/>
</composite:interface>

<!-- IMPLEMENTATION: REUSABLE FOR CREATE AND UPDATE ACTIONS-->
<composite:implementation>
    <div class="tile">
        <div class="image">#{cc.attrs.image}</div>
        <div class="title">#{cc.attrs.title}</div>
        <div class="teaser">#{cc.attrs.teaser}</div>
        <div class="article">#{cc.attrs.article}</div>
    </div>
</composite:implementation>
</html>

I tried to invoke it like this:

<!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:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:a4j="http://richfaces.org/a4j"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:rich="http://richfaces.org/rich"
    xmlns:mywidgets="http://java.sun.com/jsf/composite/widgets">

<ui:composition template="/templates/overview.xhtml">

    <ui:define name="title">Overview</ui:define>

    <ui:define name="body">

        <mywidgets:tileContainer title="Profession">
            <mywidgets:pictureTextTile title="Websockets" article="Lorem Ipsum"></mywidgets:pictureTextTile>        
        </mywidgets:tileContainer>              

        <mywidgets:tileContainer title="Sports"/>
    </ui:define>
</ui:composition>
</html>

How would I be able to insert other widgets (composites) of different types into the tileContainer below the title div?

Thanks in advance for any experienced knowledge-sharing.


Solution

  • You can use <cc:insertChildren> to specify where composite component's children should be inserted.

    <div class="title">#{cc.attrs.title}</div>
    <cc:insertChildren />