Friday, December 04, 2009

Facelets ui:include considered powerful

Just as a preface: I am very far from being a JSF or Facelets expert - more a novice.


So lately I have been looking at how to dynamically include Facelets or general xhtml snippets into my JSF/Facelets pages. One of the tags made for this is of course <ui:include>. In its src-attribute you give a path to a page to include like <ui:include src="/path/to/file.xhtml"/>. So far so cool.

Now I want to have the page to include to be dynamic - after a lot of googling I found that I can actually pass an EL expression like this <ui:include src="#{BackingBean.path}"/>. This did first not work at all, because I had a typo in the name of the backing bean - and I just got an error "there is an error" :-/ After the typo was fixed, I was able to get the path from the backing bean.

Now there are situations where my included page can or should not be shown.

First (naive) approach was (we are using RichFaces):

<rich:panel rendered="someCondition">
<ui:include src="#{BackingBean.path}"/>
</rich:panel>

But no matter the condition, BackingBean.path was evaluated and this could return something that does not point to the file, which screwed up the whole page with the above "there is an error" message.

So I ended up with creating an empty page, that I put into the webapp and my BackingBean.path now looks like this:


public String getPath() {
if (someCondition)
return stringExpression;
else
return "/path/to/empty.xhtml";
}


This works like a charm.

And I also found out that the src-attribute of ui:include actually is an URL, which means, that it is possible to get the included snippet from a remote web site or from within a Jar file like


public String getPath() {
URL pathUrl = getClassloader().getResource("nameOnClasspath");
return pathUrl.toString();
}


So yes, <ui:include> is a powerful feature of Facelets.

2 comments:

Barry said...

Just so you know, this doesn't work because the EL expressions are evaluated as the page is rendered.
Try leaving EL inside a comment and you'll see it's still evaluated.

Heiko said...

Barry, what exactly does not work? The solution did work well for me at the time I wrote this. So could you please elaborate?