myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Simon Kitching <>
Subject Re: f:attribute in phaselistener
Date Fri, 20 Apr 2007 02:31:12 GMT
Hi Ernani,

If your application always uses the same values for the f:loadBundle tag 
attributes (ie basename and var are always the same) then you might be 
able to work around this problem with a hack: write a PhaseListener, 
then on post-restore-view, do this:
     ResourceBundle bundle = somehowLoadTheDesiredBundle();
     String var = "whatever the f:loadBundle var attribute is set to";
      new BundleMap(bundle));

The BundleMap class just makes a ResourceBundle acessable via the Map 
interface. You can copy it from the original class:

The above is ugly but probably the easiest solution in many cases.

A proper fix would involve writing a tag to replace the LoadBundleTag 
and then changing your pages to reference this new tag, eg
   <my:loadBundle basename=".." var="..."/>

Not sure what the best implementation for the new tag would be. I guess 
a UIComponent subclass could be created as for normal tags. Its 
saveState method would just save the basename and var. Its restoreState 
method would then load a bundle using basename and re-register it using var.

That's not *too* hard, but not trivial either.

BTW, I'm not *sure* that Shawn's problem is the same. I don't remember 
him mentioning anything about message bundles, just that "f:attribute 
doesn't work".

The JSF phases should be well described in any JSF textbook; it's the 
most fundamental concept of all.

You'll find lots of useful info on the myfaces wiki:



Ernani wrote:
> Hello Simon,
> You said
>           The fix is probably to update the f:loadBundle tag to reload the
> bundle during the restore-view phase.
> I am not familiar how to do this, I think I still need more study on the
> Faces phases. How do you suggest us to fix? Me and Shawn have the same
> problem.
> Any code snippet or source explaining this would be highly appreciated.
> Best Regards,
> Ernani
> Simon Kitching-3 wrote:
>> Ah.. Shawn, the value you are missing isn't taken from a message bundle 
>> is it?
>> There was a question on this list a month or so ago about using an EL 
>> expression to get a value from a message bundle. The f:loadBundle tag 
>> currently only works in the "render" phase, and does nothing on 
>> restore-view. This means that any EL expression referencing the message 
>> bundle will return null during postback processing.
>> This isn't normally a problem; messages from message-bundles are 
>> normally used just to output text. However if for some reason anyone 
>> tries to reference one in the postback (eg from a t:updateActionListener 
>> or t:aliasBean) then it won't currently work.
>> And as noted earlier in this thread, prior to myfaces 1.1.5 an 
>> f:attribute was evaluated once only and the result of the expression 
>> stored as the parent component's attribute. In 1.1.5 and later the 
>> *expression* is now stored and evaluated each time it is used. And of 
>> course the *first* time the f:attribute is encountered is during a 
>> render phase. So if you use an f:attribute to access a message bundle, 
>> then it would work in pre-1.1.5 because it evaluates once (during a 
>> render phase) and stores the resulting string. Even when that attribute 
>> is fetched during a postback phase it will be there. However since 1.1.5 
>> it will be the *el expression* that is fetched and evaluated - so the 
>> message-bundle is not loaded so the expression will evaluate to null in 
>> the postback phase (and will work fine in the render phase).
>> The fix is probably to update the f:loadBundle tag to reload the bundle 
>> during the restore-view phase.
>> Regards,
>> Simon
>> Ernani wrote:
>>> I have the same issue here, just upgraded and it is missing all
>>> parameters
>>> for messages.
>>> Please let me know if you figure it out how to resolve this problem.
>>> Otherwise I will have to downgrade the MyFaces version.
>>> Thanks.
>>> Ernani
>>> Garner, Shawn-2 wrote:
>>>> I upgraded to 1.1.5 and now my phase listener can no longer get my
>>>> f:attribute attribute on a component (eg: <h:inputText>).
>>>> I iterate over the client IDs with messages by doing
>>>> FacesContext.getClientIdsWithMessages();
>>>> I get the component by UIViewRoot.findComponent(clientID) and then try
>>>> to get the attribute by String fieldRef =
>>>> component.getAttributes().get("fieldRef");
>>>> It worked before I upgraded.
>>>> Can somebody help me?
>>>> Shawn 

View raw message