How to use Internationalized messages

Extensibility
Extensibility covers the mechanisms by which you, as the user or developer, can extend the functionality of the Teradata Database, for example with the use of User Defined Functions, or UDFs.
Teradata Employee

How to use Internationalized messages

The following article describes how to internationalize the content within your portlet.

JSP

For most portlets, the JSPs (the View in the MVC) are where the bulk of the localization will be done. Strings are easily localized using the fmt:message tag.

...
<!-- localize an anchor text -->
<a href="#${context}overview" tabindex="1"><fmt:message key="detail.label.overview"/></a>
...
<!-- parameterized message -->
<div class="message">
<fmt:message key="detail.message.session-not-connected">
<fmt:param>${sessionNumber}</fmt:param>
<fmt:param>${systemName}</fmt:param>
</fmt:message>
</div>

<!-- User's current locale is available as a request attribute on any jsp -->
<c:out value="${locale}" />

The corresponding entries go in the messages.properties file

detail.label.overview=Overview
detail.message.session-not-connected=Session {0} is no longer logged on to {1}

Note: The spring:message may also be used. We prefer the fmt:message tag as it spits out a particularly ugly message (?detail.label.overveiw?) if the string is not found in the resource-bundle, making errors easier to spot.

Note: Most IDE's have some sort of in-built support for internationalization. E.g., to localize a String in IntelliJ, select the word/phrase, rt-click and choose the Refactor > Internationalize menu. It auto creates a key for you & lets you select the .properties file to add the entry to.

Java (Controllers etc)

Sometimes, it is necessary to perform the localization before the data is sent to the View. There are very few good reasons to do this, the most common situation is when you are internationalizing an existing portlet, and want to make as few changes as possible.

In this case, the best mechanism would be to add a MessageSource property to the class that is going to be responsible for the localization, and wire it up using Spring. You can then lookup the localized value for the String using the getMessage method.

...
private MessageSource messageSource;
...
public void setMessageSource(final MessageSource messageSource)
{
DbcUtil.throwIfNullArg("messageSource", messageSource);
this.messageSource = messageSource;
}
...

final String SYSTEM_NAME_NO_SYSTEM = messageSource.getMessage("no.systems", null, ctx.getLocale());

Java Taglibs

Taglibs may be treated as an extension of the View, since they are also responsible for transforming and displaying data in some format. In order to localize a String, you need the following:

  • Key: The key to use to look up the localized string.
  • Locale: The target locale for which the string needs to be localized. This will be the users current locale.
  • MessageSource: The ResourceBundle which contains the localized strings.

The key will usually be the String itself, or a descriptive phrase if you so choose. The locale may either be passed in as a property, or may be inferred as shown below. The messageSource also needs to be looked up from the Web ApplicationContext. (Exception handling removed for clarity)

public class SomeTag extends SimpleTagSupport
{
private MessageSource messageSource;

public void doTag() throws JspException, IOException
{
...
String localizedValue = this.getLocalizedString(key);
...
}

private String getLocalizedString(final String key)
{
PageContext pageContext = (PageContext) getJspContext();
ServletRequest request = pageContext.getRequest();
Locale locale = RequestContextUtils.getLocale( (HttpServletRequest) request);

String value = this.getMessageSource().getMessage(key, null, locale);

return value;
}

public MessageSource getMessageSource() throws JspTagException
{
PageContext pageContext = (PageContext) getJspContext();
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(pageContext.getServletContext());

messageSource = (MessageSource) context.getBean(MESSAGE_SOURCE_BEAN_NAME);

return messageSource;
}

// An alternate (shorter) technique is as shown below

/* Alternate method
PageContext pageContext = (PageContext) getJspContext();
ServletRequest request = pageContext.getRequest();

LocalizationContext locContext = BundleSupport.getLocalizationContext(pageContext);
ResourceBundle bundle = locContext.getResourceBundle();

Locale locale = RequestContextUtils.getLocale( (HttpServletRequest) request);

String value = bundle.getString(key);
*/
}

Date/Number Formatting

Date and number formatting are typically easy to do using the fmt:formatNumber and fmt:formatDate taglibs in the JSPs, or using the NumberFormat or DateFormat classes. However, in many cases for Viewpoint portlets, numeric data is fed into the widgets, which are programmed to work with the raw timestamp or numeric data. In that case, it is best to leave the data unformatted, and let the widget handle the localizing.

...
<fmt:formatNumber value="${session.numericValue}" maxFractionDigits="1"/>
...
NumberFormat numberFormat = NumberFormat.getInstance(locale);
numberFormat.setGroupingUsed(false);
numberFormat.setMaximumFractionDigits(1);
result = numberFormat.format(value);

Javascript

As with JSP's fmt:message tag, formatting messages in JavaScript is straightforward, with the jQuery.i18n.gettext()function. In the simple case, it takes two arguments: your portlet context, and the name of the message:

jQuery.i18n.gettext("${context}", "detail.label.overview");

If the message takes parameters, pass them as additional arguments to the function:

jQuery.i18n.gettext("${context}", "detail.message.session-not-connected", "${sessionNumber", "${systemName");

Assuming you're portlet uses the vp:registerPortlet tag, this is all you'll need, as that tag automatically loads your portlet's messages into JavaScript for you.

If you need to explicitly load your portlet's messages into JavaScript yourself, you can use jQuery.i18n.loadContext():

jQuery.i18n.loadContext("${context}");