In Facelets prior to JSF 2, composition components were fairly easy to use and understand. I must say, such is not the case any longer with the same feature in JSF 2. Here is my problem:
One use I made of composition components in Facelets (JSF 1.2) was to encapsulate the repetitive coding needed for columns in a dataTable. I cannot seem to get this to work at all in JSF 2. I understand that there is a <composition:facet> tag, a <composition:insertFacet> tag and a <composition:renderFacet> tag. I cannot find a single example anywhere as to how these tags would be used. I'd like to do something like this:
And have the client page use it this way:
Obviously with values passed in to represent the beans properties to be displayed. I have had no luck doing this, and was wondering if anyone on this forum has enough experience to tell me (a) how this might be done, and (b) what the general use of the facet tags is.
I'm confused here. I thought that the difference between JSF 1.x and JSF2 was that Facelets is integrated into JSF2 but had to be added manually to JSF1 apps.
In any event, I'm doing Facelets tags using ui:include in JSF2 just fine myself.
I couldn't find a whole lot out about any "cc" namespage tags, except for one blog entry. Which made me wonder if the author hadn't simply defined "cc" as a custom tagset himself.
An IDE is no substitute for an Intelligent Developer.
Joined: Mar 30, 2006
OK, maybe I'm the one confused, yet again!
JSF 2 does, indeed, include Facelets...and it no longer needs to be configured in faces-config.xml as it did in JSF 1.2. However, a few things have been added to Facelets in JSF 2. Composition components (as opposed to templating) have undergone a change, but it's possible that the previous strategy is still supported...I never thought to check that. A composition component is defined as an XHTML file in a specific location in the web project, and accessed via a tag (the tag being the name of the file itself). As a namespace, the prefix is arbitrary...I have seen it both as cc: as well as composition:. This new approach recommends that two distinct areas within the file be specified...one that represents the interface (<composition: interface>), and the other representing the implementation (<composition: implementation>). The difference is that the interface defines the way in which the client page would use the tag, typically identifying attributes that are then used within the implementation. The implementation is the code that replaces the tag when compiled.
I will have to check to see whether my old code still works. If it does, sweet! I'm still interested in finding out how to use the various facet tags, but that can wait for another day. A better day. Perhaps a day when I have a functioning brain.
It looks like you've been referring to what I know of as "custom tags via facelets". And, unless I'm mistaken the two element types are like the way we did C/C++, with external definitions separated from the implementation. I've used this feature, but it was several months back. It's not that hard, actually.
But the old include technique still works as well. I've been using it this very morning.
This is an interesting point. Firstly the use of "cc" or "composite" is purely dependent
on the prefix you use in your namespace declaration and "cc" is widely used. Just
remember that all the docs will refer to composite:.
The insertFacet and renderFacet tags are intended to allow the composite component
itself to have (or not have) facets (i.e. on the calling page):
Then there are two scenarios within the composite component worth
considering regarding the use of renderFacet and insertFacet:
cc:renderFacet is rendering the facet as a child component of the composite component,
which is fine, in this context it's "standalone", there's no parent component that can take
cc:insertFacet is adding the facet to the h:dataTable's facet map, which is what it's supposed
to be doing in this context. The big point is that in the code above if you use cc:renderFacet
within the dataTable there is no output, if you use insertFacet it works as expected. Equally
if you use insertFacet in place of renderFacet above, there is no output.
I thought you might be able to achieve simple code replacement doing something
But this doesn't work. I think that the problem is that we're trying to add the
header facet to the facet map of h:dataTable, but it's being added to the facet
map of the composite component and stays there.
What you can do is have a file containing content within <ui:composition> tags that
you ui:include into the main file. I tested this as follows and it works:
You can add a ui:param child tag to ui:include which makes it fairly useful:
I don't know if this would help with what you want to do but it's got to be worth
looking into. The facelets templating mechanism in general can do a lot for you
but is far from intuitive, but in the long run it'll save you a lot of time.
Joined: Mar 30, 2006
Brenden, I have to thank you immensely for the help. This is exactly what I needed, and I appreciate the guidance.
This leads to another observation...composition components are obaque enough that a really, really good article or book is badly needed. Badly. And again (although I understand it might be more powerful) the original way in which composition components worked was pretty darn easy. This is not. I can't help but wonder what the JSF 2 committe was thinking in designing an approach that is far, far less intutive.
Joined: May 12, 2009
Glad it was of help, writing it down helped me understand it myself. It hit a problem
yesterday where I was getting an IndexOutOfBoundsException in a composite component
and this turns out to be due to a bug when using hutputStylesheet and cc:insertChildren
in the same cc.
I was able to work around this by replacing hutputStylesheet with link type="text/css"