JSF <h:outputFormat>: use array values as parameters
Asked Answered
B

1

6

On my JSF2 page, i'm using internationalized error messages.

In my backing bean, i'm putting the messages into the flash Scope:

flash.put("error", exception.getType());

On the page, this string gets translated this way:

<h:outputText value="#{bundle[flash.error]}"/>

Works fine.

NOW i want to be also able to put (an arbitrary number of) parameters into the message text, that get inserted into the placeholders in the i18n-property in my message.properties. Therefore, i'm putting the parameters as a String array into the Flash Scope, like this:

//exception.getParameters returns String[]
flash.put("errorParams", exception.getParameters())

Now i also want to be able to use this String array as parameters for an outputFormat element, to insert them into a property like Welcome, {0} {1}. So i tried to achieve this by using ui:repeat:

<h:outputFormat value="#{bundle[flash.error]}" rendered="#{! empty flash.error}" class="invalid">
  <ui:repeat value="#{flash.errorParams}" var="_param">
    <f:param value="#{bundle[_param]}"/>
    <!-- also doesn't work: <f:param value="#{_param}"/>-->
  </ui:repeat>
</h:outputFormat>

Unfortunately, the param value is ignored and the placeholders of the i18n-property aren't replaced, so the rendered output is Welcome, {0} {1}. When using a "regular" repeater, displaying the array elements just as an outputtext, it works. So the outputFormat tag doesn't seem to support the use of a repeat as a child. Damn, so close ;) Anyone knows a good way to do what i want, or is there any component library supporting something like that?

Burble answered 16/7, 2010 at 12:5 Comment(0)
W
8

The problem here is that ui:repeat is a render-time child of h:outputFormat which it indeed doesn't support at all. You'd like to put multiple f:param elements directly as children of h:outputFormat during build time.

The c:forEach is suitable for this task. The JSTL core tags (which are already included in Facelets, so you don't need to install any extra JARs) do their job during building the view tree, right before it's JSF turn to process/render the view tree.

<html xmlns:c="http://java.sun.com/jsp/jstl/core">
...
<h:outputFormat value="#{bundle[flash.error]}" rendered="#{! empty flash.error}" class="invalid">
  <c:forEach items="#{flash.errorParams}" var="_param">
    <f:param value="#{bundle[_param]}"/>
  </c:forEach>
</h:outputFormat>
Workaday answered 16/7, 2010 at 12:35 Comment(3)
Yeah, just discovered it some days ago. I had problems with FacesMessages as they don't survive redirects (which i do often), so i'm using the Flash-Scope instead, which is an ideal replacement.Burble
@ifischer what do you mean by "FacesMessages as they don't survive redirects " ?Amputate
@Tarik: they're request scoped.Workaday

© 2022 - 2024 — McMap. All rights reserved.