Tricky localization and custom messages question

Hello,

After googling for tips on customizing the standard error messages for JSF, I came up with the following scheme. I added a PhaseListener for the render response phase. The PhaseListener iterates over the registered messages by client id; finds the component that is the label for the given client id using the "for" attribute; uses the value of the label component to replace a fixed string in the messages (e.g. "[label]"). So given the following:

<h:outputLabel value="Name" for="nameInput"/>

<h:inputText id="nameInput" value="#{myBean.name}" required="true" />

It correctly replaces the string "[label]" with "Name" in the messages for the input component. E.g. "Name: Field Name is required." So far so good, I'm feeling pretty clever.

Now I am trying to localize my application. So I replace the above with:

<f:loadBundle basename="com.xyzzy.labels" var="labelProps" />

<h:outputLabel value="#{labelProps.name}" for="nameInput"/>

<h:inputText id="nameInput" value="#{myBean.name}" required="true" />

Now the outputLabel component no longer has a value attribute. A little digging, and I see that instead it has a ValueBinding (I am using MyFaces 1.1.0 => JSF 1.1 => no ValueExpression). OK, I'll evaluate the expression and use the result. No luck there, since the resource bundle hasn't been loaded (presumably that happens during the render response phase, this is in the beforePhase() method). OK, I'll use the literal EL expression and maybe it will get evaluated by the <h:messages> component. No dice, the literal EL expression appears.

Any suggestions?

Thanks,

Ray

P.S. Sorry for the re-post but I cannot locate my original thread.

[2082 byte] By [RaymondDeCampoa] at [2007-10-3 7:43:12]
# 1

Try to load the properties in a separate ResourceBundle class (could be static one).

ResourceBundle rBundle = ResourceBundle.getBundle(path, myLocale);

and

rBundle.getString(key);

In your phaseListener just call i for desired key and change value.

Regards,

Stas

StanislavLa at 2007-7-15 2:44:16 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2

The problem with that approach is that I do not know what resource bundle the label is coming from, or even if it is a resource bundle, it could be from a backing bean.

To be more explicit, all I have is the EL expression. Since the properties are mapped to a variable via <f:loadBundle> I would have to get my hands on the <f:loadBundle> tag to determine what bundle it is.

RaymondDeCampoa at 2007-7-15 2:44:16 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3
Use FacesContext.getCurrentInstance().getViewRoot().getLocale() to get the current locale.Regards,Stas
StanislavLa at 2007-7-15 2:44:16 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 4

The issue is not getting the necessary locale.

The issue I have discovered with my implementation of the idea is as follows. I am in the beforePhase() method of a PhaseListener tied to the render response phase. I discover that a value on a UIComponent is bound to an EL expression, e.g. #{xyzProps.nameLabel}. When I try to resolve that EL expression, I get a null result. I assume this is because the xyzProps variable is not bound yet, because it is defined by a <f:loadBundle> instance.

What are my options here? Is it even possible to try to access the <f:loadBundle> tag to discover what resource bundle is used? Am I listening at the wrong phase? Should I scrap my current strategy for solving the bigger problem? What is another strategy?

RaymondDeCampoa at 2007-7-15 2:44:16 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 5

Why do you try to extract something from the <f:loadBundle>?

If you need current locale use root view's locale.

If you need a value by key from .properties file you can get the value without <f:loadBundle>. Use ResourceBundle for this. Load necessary bundle using the locale from root view.

Regards,

Stas

StanislavLa at 2007-7-15 2:44:16 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 6

You are focusing on the message bundle aspects and are missing both the specific issue and the big picture.

Here is the specific issue I am with my current implementation. I have a PhaseListener that has obtained a handle on an HtmlOutputLabel instance. The value of this instance is an EL expression. I would like to evaluate the EL expression within the PhaseListener. Unfortunately, since the EL expression sometimes refers to bundles loaded with <f:loadBundle> this does not appear to be possible.

The big picture is that I would like to be able to have the validation error messages generated by Faces to contain the label used within the HTML page when they are rendered. I have seen suggestions and implementations that break down once the labels are not simple text, but are EL expressions.

RaymondDeCampoa at 2007-7-15 2:44:16 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...