at.
at.

Reputation: 52510

i18n translation in JSP custom tag

Is it possible to write a custom JSP tag to take an i18n message key and output the translation phrase for the given request?

Normally in JSP/JSTL, I do:

<fmt:message key="${messageKey}"><fmt:param>arg1</fmt:param></fmt:message>

And I get the translation phrase. Now I need to do the following (there's a good reason for this):

<custom:translate key="${messageKey}" arg="arg1"/>

But I don't know how to look up the translation in the custom tag code. The TagSupport base class provides a pageContext from which I can get a ServletRequest which has the Locale... but how do I then look up the translation for a key?

I use Spring 3.0 and in my application-context.xml, I've defined a ReloadableBundleMessageSource so I can call:

messageSource.getMessage(
    key, new Object[] {arg}, pageContext.getRequest().getLocale()
);

but I don't think I can inject messageSource into a custom tag, can I? Otherwise I can instantiate a new one, but would it load my tens of thousands of translations for every call? I don't want to resort to making messageSource a static member of a static class.

Upvotes: 3

Views: 4645

Answers (3)

Antonio Lopez
Antonio Lopez

Reputation: 165

This question is very old but I think it is worth to share another way to solve this.

To access the Spring message source in a custom tag you only need to extend the class org.springframework.web.servlet.tags.RequestContextAwareTag instead of TagSupport.

In this case you have to implement the method doStartTagInternal() instead of doStartTag(), but inside this method you will have access to the MessageSource through getRequestContext().getMessageSource() method.

Therefore, your class would look like:

public class CreateCustomFieldTag extends RequestContextAwareTag{
   //variables (key, arg...), getters and setters
   @Override
   protected int doStartTagInternal() throws Exception {
      getRequestContext().getMessageSource().getMessage(
          key, new Object[] {arg}, getRequestContext().getLocale());
   }
}

Upvotes: 0

Kristiaan
Kristiaan

Reputation: 406

There is a utility in spring to access the web application context. Then you can look up a bean by its name or type. To get hold of your resource bundle, you could do something like:

WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(pageContext.getServletContext());
messageResource = springContext.getBean("messageResource");

Upvotes: 1

BalusC
BalusC

Reputation: 1108712

I don't do Spring, but in "plain" JSP you can just put the ResourceBundle instance in the session scope with help of a Filter or Servlet

ResourceBundle bundle = ResourceBundle.getBundle(basename, request.getLocale());
request.getSession().setAttribute("bundle", bundle);

And treat it in JSP like any other bean in EL.

${bundle[messageKey]}

It must be possible to have Spring to put that as a bean in the session scope.

Upvotes: 2

Related Questions