Wiki

Clone wiki

javarosa / ExternalizedStringFormat

Locale Resource Management

Overview

Locale resources are located in text files that are situated inside of the packaged jar. There exists a set of default locale resources that are available to all projects and provide internationalized text for standard JavaRosa resources. Individual deployments can register additional resources to localize strings unique to that application, or to change the default localizations.

Important Background

Terms: '''LocaleManager''', '''Module'''

Concepts : '''Localization''', '''Ant Build'''

Pages : [wiki:Internationalization Internationalization Guide]

File Format

Language resource files are maintained as a flat text file specifying a list of key/value pairs separated by newlines. Comments can be made in the file as escaped by the '''#''' character. Arguments can be specified using the delimiter ${} . Instructions for utilizing arguments in internationalization can be found on the [wiki:Internationalization Internationalization Guide].

The language of a resource file is unspecified. The application is responsible for associating a resource file with a locale.

'''Example'''

# This is an example of a language resource file.

menu.Save=Save
menu.Exit=Exit

login.nouser=The user ${0} does not exist. # Example of an argument that can be provided. In this case, probably with a stack of parameters
login.fail=Bad Username/Password Combination

Common Language Resources

The '''org.javarosa.resources''' project contains a common set of language resources that covers the set of strings which are utilized by most JavaRosa projects. It is recommended that new deployments use this project and register its LanguagePackModule in order to provide general locale support.

If you are providing a new translation for JavaRosa, it is recommended that you add that translation to the common resources project so that locale can be made available for other implementers.

The method used to import the Language Resource Files from the resource project is provided below in the '''Importing Resources''' section.

Registering Resource Files

'''Note: This method of registration will probably become more generic in the future.'''

New resource files should be registered with the LocaleManager with a specified locale to make those localizations available to the application. This process should occur early in the application's initialization, in case localized strings are necessary for other modules. Registering an English resource file would look like the following example:

    JavaRosaServiceProvider.instance().getLocaleManager().registerLocaleResource("english","/english_translations.txt");

Conflicts between values for individual text keys are settled by the last registered resource, so if you want to override the common or default translations, resource files registered after the standard ones will successfully override them.

Locales must be added to the locale manager before resources can be registered to them. If you have registered the LanguagePackModule many of these locales will be added for you. You should take a look at the module to identify which ones have been provided. If you are not using the Language Pack, or want to use a new locale altogether, you can add it to the LocaleManager as follows

    JavaRosaServiceProvider.instance().getLocaleManager().addAvailableLocale("uniquelocale");

Importing Resources

The J2ME Polish build process is used to import language resource files into the jar. Unfortunately, J2ME Polish has its own localization framework that we want to avoid using due to some inherent limitations, and this process steps on the feet of ours sometimes. As such, care must be taken to ensure that resources are imported correctly. Resource importations occur in the BuildPolish target with the resources tag. The standard importation is as follows

				<!-- Resources that should be used in the Polish build (images, the polish.css file, etc) --> 
				<resources
					dir="${dir.resources}"
					defaultexcludes="no"
					excludes="readme.txt, .svn, *.css">
					<root dir="${dir.resources.external}"
						excludes=".svn"/>

					<!-- This is confusing. We're actually not using this system, and this code is here to 
                                             prevent it from causing problems. -->
					<localization>
						<locale name="none" />
					</localization>

				</resources>

The ${dir.resources} folder is a path to the local application's resources folder, while ${dir.resources.external} is a path to a set of external common resources like the '''org.javarosa.resources''' project's '''resources''' directory.

The '''localization''' tag is confusing because it implies that it has something to do with how JavaRosa is internationalized. This is untrue. J2ME Polish and JavaRosa use very similar names for many of their localization files, and if Polish intercepts a locale file, it will prevent it from properly importing as a resource. The locale name provided ("none") exists for the same reason, since it will cause polish to capture files like "messages_none.txt", which are unlikely to exist.

Some important other features of this resource block

  • '''defaultexcludes="no"''' - This is important because it prevents polish from deciding that the Language Resource files are for polish to absorb, which will prevent them from ending up in the Jar.
  • '''excludes="readme.txt, .svn, *.css"''' - Since the defaultexcludes no longer exist, some of the other common file formats need to be excluded manually.

Troubleshooting

You get the error "Failed to load locale resource FOO Is it in the jar?"

There are a few causes for this problem. First, unzip the jar and ensure that the message is correct that the file is not in the root of the jar. If it isn't, ensure that you're including the proper resource directories, and that other files from those directories are ending up in the jar. Finally, try renaming the file to get around Polish swallowing it.

Updated