Adam Warski

28 Apr 2008

Value-to-variable binding “let” tag for JSF, Facelets and Seam

java
jsf

The “let” tag enables you to bind the value of any expression to a variable and later reuse it, without recalculating the value. The concept comes of course from functional programming. It is especially useful with Seam’s extended EL.

The usage is really simple:

<mamut:let var="result" value="#{anyElExpression}">
   Now you can use #{result} as a normal variable.
</mamut>

I was looking at other tag libraries but couldn’t find anything similar. Or maybe there is?

The use case that motivated me to write this comes from the JBoss.ORG feeds application. There, in several places I have code similar to the following one:

<ui:repeat var="group" value="#{groupsService.all}">
   <s:fragment rendered=
      "#{groupsService.accFeeds(group).size() > 0}">
      (some header)
      <ui:repeat var="feed"
         value="#{groupsService.accFeeds(group)}">
         (...)
      </ui:repeat>
   </s:fragment>
<ui:repeat>

Of course calling groupsService.acceptedFeeds(group) twice is unnecessarily inefficient. I could move this call to a backing bean, but doing so would only cause me to write some really simple code many times. The version using the let tag calls the method only once:

<ui:repeat var="group" value="#{groupsService.all}">
   <mamut:let var="acceptedFeeds"
      value="#{groupsService.accFeeds(group)">
      <s:fragment rendered="#{accFeeds.size() > 0}">
         (some header)
         <ui:repeat var="feed" value="#{accFeeds}">
            (...)
         </ui:repeat>
      </s:fragment>
   </mamut:let>
<ui:repeat>

If somebody finds this useful, I’ve put the jar here. To use it, just bundle the jar with your application. The namespace for the tag is the following:

xmlns:mamut="http://mamut.net.pl/jsf"

Adam

comments powered by Disqus

Any questions?

Can’t find the answer you’re looking for?