10

I have use case in which I have to use resource bundle to display various texts on UI. Some of these resource bundle entries take paramets (e.g. {0}), for these I use h:outputFormat but sometimes that isn't enough.

e.g.

someMessage=Display this message with param {0}

in a resource bundle.

To display it on xhtml I normally do:

<h:outputFormat value="#{msg['someMessage']}"><f:param value="#{someBean.value}"/></h:outputFormat>

That works well when it's a simple case, but for more complex use cases it isn't enough. For example if I want the 'title' attribute of a commandLink to use the above resource bundle entry:

    <h:commandLink action="logout" title="#{msg['someMessage']}">
        <f:param value="#{someBean.value}" />
        <h:graphicImage library="images" name="image.png" />
    </h:commandLink>

which doesn't work. I also tried:

    <h:commandLink action="logout">
        <f:attribute name="title">
            <h:outputFormat value="#{msg['someMessage']}"><f:param value="#{someBean.value}"/></h:outputFormat>
        </f:attribute>
        <h:graphicImage library="images" name="image.png" />
    </h:commandLink>

which also doesn't work since f:attibute doesn't allow children.

Even if there is a hack to bypass this (e.g. using hover component from primefaces) there are other fields that might require a parameterized message.

Does anyone know of a way to use MessageFormat that takes an argument in a non-value field of a JSF component?

Zak
  • 359
  • 2
  • 10
  • Similar question: http://stackoverflow.com/questions/5697189/pass-parameters-to-messages-from-resource-bundle-to-components-other-than-hou – Adam Aug 17 '12 at 10:22
  • That's a different question since that one is regarding the **value** attribute, which is straight forward to deal with (I answered the question). A way to use parameterized MessageFormat with **non-value** attributes is what I'm looking for. – Zak Aug 17 '12 at 16:16

1 Answers1

9

You could create a custom EL function for this with which you can ultimately end up like:

<h:commandLink ... title="#{my:format(msg['someMessage'], someBean.value)}" />

You can use the MessageFormat API to perform the job, exactly as <h:outputFormat> is doing under the covers.

An alternative is to create a custom component which does the same as JSTL's good 'ol <fmt:message> which supports a var attribute to export the formatted message into the EL scope.

<my:outputFormat ... var="linkTitle">
    ...
</my:outputFormat>
<h:commandLink ... title="#{linkTitle}" />

Update: JSF utility library OmniFaces has #{of:formatX()} functions and a <o:outputFormat> component for the very purpose.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • The problem with that approach is that you require a new method if your messageFormat takes 2 parameters, and yet another method for one that takes 3 parameters, etc. Is there a more elegant way of doing this? If not, then it should be added to future releases of JSF since it's something that should be supported by default. – Zak Aug 17 '12 at 17:24
  • No. EL doesn't support varargs (also no overloaded function names, so you really need `format1()`, `format2()`, `format3()`, etc). Note that this is not a JSF limitation, but an EL limitation. Just create functions taking 1 to 5 parameters, or maybe 10. I've personally never created/seen in real world a bundle entry with more than 5 parameters by the way. – BalusC Aug 17 '12 at 17:28
  • No, what I think is required is a way to use f:attribute with children. That way, you can just set the name of f:attribute to the name of the attribute to use messageFormat (e.g. title) and its child can be a h:outputFormat (my second attempt above is agood example of this). That would make messageFormat useable everywhere as long as all components can have an f:attribute child. – Zak Aug 17 '12 at 17:36
  • 3
    Nice idea, but the `` doesn't work that way :) I'd rather prefer a `var` attribute for the ``, in line with how JSTL's good 'ol `` works. Perhaps another idea for OmniFaces. – BalusC Aug 17 '12 at 17:46
  • That would be awesome and would definitely help the internationalization/localization team on my project. Soon, OmniFaces is going to become the Apache Commons of JSF! – Zak Aug 17 '12 at 17:54
  • Thanks for the tip. I hadn't heard of OmniFaces before; this library will be very useful. – Haroldo_OK Nov 05 '12 at 13:07