Saturday, July 3, 2010

Output JSF messages with static and dynamic key parts or the power of JSTL c:set

At the beginning of my development with JSF I faced a problem when I tried to get messages if one part of key is static (fix) and the other one is dynamic. Let us suppose you have the following keys and messages in your property file
breadcrumb.overview=Overview
breadcrumb.new=New
breadcrumb.edit=Edit
....
and would like to output these messages in a loop with ui:repeat like this
<ui:repeat value="#{breadcrumbBean.items}" var="item">
   ...
   read and output messages with h:outputText
   ...
</ui:repeat>
Suppose the exported variable for the current item of the iteration "item" has a property "name" which references the dynamic part of key. In our case that are parts "overview", "new", "edit", ... The prefix "breadcrumb" is in contrast fix. If you try now
<h:outputText value="#{msgBundle['breadcrumb.' + item.name]}" />
or
<h:outputText value="#{msgBundle['breadcrumb.'item.name]}" />
or
<h:outputText value="#{msgBundle[breadcrumb.item.name]}" />
nothing works. What is the right syntax? Here is a solution:
<c:set var="key" value="breadcrumb.#{item.name}" />
<h:outputText value="#{msgBundle[key]}" />
JSTL c:set buffers at first the entire key in a scoped variable "key", so that h:outputText can access it later.

By the way, c:set is very helpful in JSF 2 if you want to assign a dynamically Id to any JSF compoment. Component Id can not be set dynamically by EL. It's a static string. You can not write e.g.
<h:panelGroup id="#{myId}" layout="block"/>
What is a possible solution? Use the implicit object "component" to point enclosed component in c:set "target" atribute. An example:
<h:panelGroup layout="block">
    <c:set target="#{component}" property="id" value="#{idPrefix}panelGroup"/>
</h:panelGroup>
That's all!

3 comments:

  1. Thank You!!
    It was a big help form me!!

    ReplyDelete
  2. What do you think about this solution?

    #{msgBundle['breadcrumb'.concat(item.name)]}

    ReplyDelete

Note: Only a member of this blog may post a comment.