Help

Controls

PermLinkWikiLink

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

Forum: Seam Users Forum ListTopic List
27. Mar 2008, 17:46 CET | Link

Hi,

I use the Seam messages component but I need the key to be dynamically generated.

For example I want my label keys to start with label. then concatenate a value coming from an iteration.

I tried this :

<ui:repeat value="#{task.transitions}" var="transition">
	<s:button value="#{messages['label.#{transition}']}" 
	action="..."  />
</ui:repeat>

But it doesn't work. Anyone know if it possible thanks to Seam EL enhancements ?

 
Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. (Albert Einstein)
5 Replies:
27. Mar 2008, 18:12 CET | Link

You can't specify an expression inside an expression like that. You might want to lookup concentenate JSF functions to combine 'label.' with transition to pass into messages. There was a thread about this last week I think (search for concatenate).

Or you could always override the org.jboss.seam.international.Messages class (where #{messages} comes from) and put your label. in there. Usage would then be something like

<s:button value="#{mymessages[transition]}" />

Cheers,

Damian.

Rating:  * * * *
28. Mar 2008, 10:33 CET | Link

Thanks Damian for your response. I like your suggestion of overriding the Messages class. Unfortunately the label. prefix was just an example and most of the time I have no idea what the prefix will be.

Anyway I created a Seam component to solve my problem.

@Name("messageUtils")
@Scope(ScopeType.STATELESS)
public class MessageUtils {

	public String getDynamicMessage(String prefix, String key) {
		StringBuffer sb = new StringBuffer();
		sb.append(prefix);
		sb.append(key);
		return SeamResourceBundle.getBundle().getString(sb.toString());
	}
}

Then I can use it this way :

<ui:repeat value="#{task.transitions}" var="transition">
    <s:button 
        value="#{messageUtils.getDynamicMessage('label.demandeAbsence.', transition)}" 
	action="#{validationDemandesAbsenceAction.choisirTransitionTache(task.idTache, transition)}"  />
</ui:repeat>

Best regards,

Olivier

 
Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. (Albert Einstein)
28. Mar 2008, 11:20 CET | Link

No worries. You should probably throw an @BypassInterceptors on that class as well. For usage like this it improves performance (there's a long long thread on it somewhere in this forum).

And if you're well keen, then apparently EL functions are more performant that using a Bean in this manner (although I use them the same way as this without any trouble).

Cheers,

Damian.

28. Mar 2008, 12:01 CET | Link

Thanks for the tip about @BypassInterceptors.

About EL functions, will it be possible to use Seam built-in components if the class containing the EL functions is not itself a Seam component ? And then I can't see the difference between EL functions and Seam components. I had posted a JIRA about the ability to extend the list of EL functions supporters by Seam EL resolver a few months ago, don't know if it has been token in account.

By the way, I have another strange problem with dynamic EL expressions. The transition variable is known when using my messageUtils component. But when I use my other component on action attribute of my s:button, the transition variable is an empty string !

Can't understand why since there is no problem with task.idTache parameter and both methods consider transition parameter as a String ... Do you have any idea where it could come from ?

 
Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. (Albert Einstein)
28. Mar 2008, 13:08 CET | Link

EL functions are static methods on simple class (non-seam component).

But you can pass on the request to a seam component however....

e.g.

	public static String descriptionForOptionList(String listKey, String value) {
		UserPreferencesBean bean = (UserPreferencesBean)Component.getInstance(UserPreferencesBean.class, ScopeType.SESSION);

		return bean.descriptionForOptionList(listKey, value);
		
	}