Skip to end of metadata
Go to start of metadata


The translations may be done using the LAMS Community website The modules to be translated are available there, and then the data is downloaded and checked into our source code set on a regular basis.

There is a demonstration (written in Italian) on how to do a translation available on from or there is an English version. With the English version, your browser might try to download the htm file - allow it to download and open the file and then it will access the animation from this server.

The rest of this document covers "how" the I18N parts work.  


Properties Files and Dictionary Folder lams-dictionary.jar

Internationalisation of LAMs breaks into two parts:

  • the Java side for the tools and most of the core functionality, and
  • the Flash side.

The Flash side is covered separately. The Java side is done using properties files which are named <something>.properties. They are also known as message resources or language files. These files are placed in the lams-dictionary.jar in the lams.ear (in JBOSS). This appears as folder on filesystem.

If you are manually updating properties files during development, you can place the new files can be placed directly in this folder and LAMS restarted to pick up the new files. If an error exists in the translation then the file in the folder can be modified and LAMS restarted to pick up the new files. The restart is due to how Java caches the resource files.

The tool deploy utility will copy a tool's properties files (known in the deployer as language files) to this directory. The package in which the files should be placed is specified in the "languageFilesPackage" option. See Tool Deployment for more details.

In each project is a conf/language directory. This contains two subdirectories - lams for the LAMS translations and rams for the RAMS translations. When the build is done, the appropriate language files are picked up based on the conf.application setting in (in lams_build). Please do not call the directories anything else.

During the initial development of a module, the Australian English properties file should be created manually. When the bulk of the module is completed, then the properties file should be given to Ernie to put up on the translation website. After that, the module will be translated into various languages, and the language files included in the lams code base whenever Ernie does the regular extract from the translation website. As you make changes to a properties file (either adding, removing or changing a label) you must notify Ernie of the change so that the translation website will be updated. If you do not notify Ernie, then the change will be lost next time the extract is done from the translation website. If you cannot contact Ernie, then contact Fiona.

Locale priority for i18n

In lams 2.0, users have a locale setting in their user record. This can be changed via the Edit Profile screen. New users are set up with the current system locale.

User interface locale will be decided by following priority:

  1. Users preferred locale in lams_user table in database (locale_country and locale_language).
  2. Country and language of the LAMS server (set via the admin screens)
  3. User browser client locale.

So, if the user's locale details in lams_user is missing it will fall back to the server settings, and failing that it will use the browser's client locale.

If lams can not find resource bundle file for a specified locale, the resource bundle with base name will be use. For example, if locale is zh_CN, will be used if system can not find The resource bundle file can place anywhere under CLASSPATH scope.

We started adding support for a request parameters e.g. action_url?locale=en_AU, which would make it possible to set locale in runtime. But this needed a call to request.getParameter() method in filter and it caused problems when reading WDDX packets, conflicting with request.getInputStream() method. So the code is commented out of the filter at present.


The Java properties files are created using a native encoding or in UTF-8. This must be converted to an ascii format for Java. This is done as part of the extraction process on the translation website but if you have a manually created file in UTF-8 that needs to be encoded, then use the native2ascii command that comes with with Java JDK.

Call native2ascii to ascii encoding, specifying the original file has UTF-8 encoding:

native2ascii.exe -encoding UTF-8 chinese_zh.txt


Properties file names follow a the normal Java convention. It should be ApplicationResources_{language 2 letter code}_{country 2 letter code}.properties. The language mapping is: Country is The letter code of country is optional.

Copy the property file into same folder with original English properties file (<project>/conf/language).

All property files in LAMS must have the following header:

# CVS ID: $Id$

which becomes

# CVS ID: $Id:,v 1.1 2006/03/27 22:24:32 fmalikoff Exp $ #

All tool properties files should include the following entries. They are used to internationalise the text that appears in the authoring screen for library activities (i.e. the activities that appear as icons on the left hand side of the authoring interface). If these values are not in the file (or if the tool doesn't have a properties file) then the values in the database will be displayed in authoring.

  • activity.title: The title of the library activity. This appears on the icon in the activity icon list in authoring
  • activity.description: Short description of the library activity. This appears in the text box above the activity icon listin authoring.
  • activity.helptext: Long description of the library activity. Does not appear anywhere in the interface at present.
  • Short name of the tool. Must not be the same as activity title. Does not appear anywhere in the interface at present.
  • tool.description: Short description of the tool. Must not be the same as the activity description. Does not appear anywhere in the interface at present.

For example:

activity.description=Online threaded discussion tool (asynchronous).
activity.helptext=Discussion tool useful for long running collaborations and asynchronous situations. Tool
tool.description=Tool for forums, also known as message boards.

The default package location for a tool's resource file is the main package for a tool. For example, the Forum's file is in the package While most of the entries in the file are for the user interface (so it is tempting to put it in the web directory), some of the entries are for the activity title, description, etc that are accessed in the Authoring service bean and it is not standard for a service layer object to access a web layer object!

It is important that the file is called format for the purposes of translation. The translations for tools that are bundled with LAMS are done via the LAMS Community website and the utility that generates the files expects the files to be named

A properties file is in <key>=<value> format. You must not have the same key twice, nor can you use the same value twice. If a value appears more than once, then only one entry with that value is available. For example, assume you had set both activity.title and to Forum. Then when the authoring starts the LAMS will only be able access either "activity.title" or "". If it happens to be "activity.title" that cannot be accessed, authoring will show the title from the database, not from the properties file. This may not result in an actual error message rather the users are likely to see strange entries on the screen.


Filter in web.xml

LocaleFilter is essential for web.xml. This filter will follow our locale priority to do related configuration for JSTL, STRUTS and Spring service bean:


Init-param is optional. Its default value is UTF-8.

JSP page

  • Adding page directive on the top of jsp:
    <%@ page language="java" pageEncoding="UTF-8" contentType="text/html;charset=utf-8" %>
  • Use the <lams:head> tag in the place of the standard <head> tag. This will set up pragma statements that avoid the page being cached and will include the following line in the head seection. Some browsers need this line to do the UTF-8 encoding properly.
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  • Some language entries will wrap as two line in authoring page tabs. If you notice this in your authoring pages, please fix it according to Forum tool authoring HTML code.

Some scenarios need to do i18n

JSTL <fmt:message>

Out of box support. Need not any change.

STRUTS <bean:message>

Out of box support but we prefer it if you don't use it. If the entry is missing from the language file, it can cause an error page, rather than just ?????. If you can use <fmt:message> instead, then use <fmt:message>

Service Bean

To make spring service bean i18n, the service bean needs to inject a messageService bean.

<bean id="monitoringMessageService" class="org.lamsfoundation.lams.util.MessageService" singleton="true">
   <property name="messageSource">
      <bean id="messageSource" class="">
         <property name="basename">

<bean id="monitoringServiceTarget" class="org.lamsfoundation.lams.monitoring.service.MonitoringService">
<property name="messageService"><ref bean="monitoringMessageService"/></property>
private MessageService messageService;
// Inversion of Control Methods - Method injection
public void setMessageService(MessageService messageService) {
   this.messageService = messageService;

This messageService has similar methods with, which help you get i18n value easily from resource bundle. It has two benefits as well. First, getMessage() methods need not assign any locale information(LocaleFilter will handle this). Second, getMessage() will return ?message.key? if system can not find the resource bundle file, rather than NoSuchMessageException in spring framework:
String str = messageService.getMessage("label.authoring.heading.basic");

Or with i18n message parameters:
String str = messageService.getMessage("invalid.lessonid.and.userid", new Object[]{lessonID,userID});
Servlet class
Locale preferredLoacle= request.getLocale();

Out of box support for ActionMessage etc. such as:
ActionMessage message = new	ActionMessage("label.authoring.heading.basic");
Arbitrary Code Access

In Authoring, the code that build the list of library activities needs to access tools' properties files to read the activity title, description, etc. The name and path of the properties file is stored in the lams_tool table but the code needs some way to access the resource bundle "on the fly".

To do this, the LoadedMessageSourceService (in lams.jar) will access any properties file on the classpath, given the file's name and path. To use the service, set up a reference to the LoadedMessageSourceService available in the core Spring context.

<bean id="authoringServiceTarget" class="org.lamsfoundation.lams.authoring.service.AuthoringService">
   <property name="learningDesignDAO"><ref bean="learningDesignDAO"/></property>
   <property name="learningLibraryDAO"><ref bean="learningLibraryDAO"/></property>
   <property name="userDAO"><ref bean="userDAO"/></property>
   <property name="toolActMessageService"><ref bean="loadedMessageSourceService"/></property> <------
   <property name="learningDesignService"><ref bean="learningDesignService"/></property>

Then in your service bean define the your property as you would any Spring injected property. The properties filename should be in the form "". To see it in use look at AuthoringService.internationaliseActivities().

The MessageSource is a Spring class, so see the Spring API for more details on the getMessage() call.
protected ILoadedMessageSourceService toolActMessageService;

public ILoadedMessageSourceService getToolActMessageService() {
   return toolActMessageService;

public void setToolActMessageService(ILoadedMessageSourceService toolActMessageService) {
   this.toolActMessageService = toolActMessageService;

private void internationaliseText(Object someObject, String propertiesFilename) {
   MessageSource toolMessageSource = toolActMessageService.getMessageService(propertiesFilename);
   if ( toolMessageSource != null ) {
      String message = toolMessageSource.getMessage(<key>,
            <parameters>, <default value>,
   } else {
      log.warn("Unable to internationalise the library activity "
            +activity.getActivityID()+" "+activity.getTitle()
            +" message file "+activity.getLanguageFile()
            +". Activity Message source not available");
Page Keywords: Internationalisation, Internationalization
  • No labels