Internationalization

Home
View
Created by david on 2009-07-02 11:29:41.0

Internationalization in JSXP is very straight forward:
- Tell the generator which locales you want to support
- Write different XHTML files for your locales, if needed
- Tell the framework whicht locales you support - this is done in your Application class. In our example we will support en, de, de_AT and es.
- Localize your controllers

When servicing a user request, JSXP will then use the best match between the browser locale and the locales supported by the application as the locale for this request. The user can also switch the locale manually, by prepending it's name to the path. This allows you to add links for the different languages to your web application:

http://localhost:8080/i18n/index.xhtml Will deliver the view in the browser locale, or your application default locale if the browser locale is not supported.
http://localhost:8080/i18n/de/index.xhtml Will deliver the view in the German locale.
http://localhost:8080/i18n/de_AT/index.xhtml Will deliver the view in the German (Austria) locale.
http://localhost:8080/i18n/ru/index.xhtml Will yield a "404 - Not found" error in our example, since we do not support russian.

Tell the Generator which locales you want to support

Append a comma separated list of locale names to the command line of the generator script. The list has to be the 6th argument, so you also have to specify the file name patterns. If you use eclipse, you can change this in the properties of your project - Just go to "Builders" and edit your JSXP generator builder. The command line should then look like:

${build_project} WebContent generated org.jsxp.test.i18n.web.generated "**/*.xhtml,**/*.xml" "de,de_AT,es"

Write different HTML files for your locales

Here we will write HTML files for 3 of our 4 supported locales: English, German and German for Austria. We do not write a file for Spanish.

WebContent/index.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:jsxp="http://www.jsxp.org/spec/1.0">
	<head>
		<title>Internationalization</title>
	</head>
	<body>
		<h1>$(.Greetings) World</h1>
		<p jsxp:id="content">In your country, the first month of the year is called January.</p>
	</body>
</html>

WebContent/de/index.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:jsxp="http://www.jsxp.org/spec/1.0">
	<head>
		<title>Internationalization</title>
	</head>
	<body>
		<h1>$(.Greetings) Welt</h1>
		<p jsxp:id="content">In Ihrem Land heißt der erste Monat des Jahres Januar.</p>
	</body>
</html>

WebContent/de_AT/index.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:jsxp="http://www.jsxp.org/spec/1.0">
	<head>
		<title>Internationalization</title>
	</head>
	<body>
		<h1>$(.Greetings) Welt</h1>
		<p jsxp:id="content">In Ihrem Land heißt der erste Monat des Jahres Jänner.</p>
	</body>
</html>

Tell the framework whicht locales you support

/*
 * Copyright 2009 JSXP-Developers-Team

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
package org.jsxp.test.i18n;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.jsxp.framework.Context;
import org.jsxp.framework.ViewController;
import org.jsxp.framework.web.WebApplication;

public class I18nTestApplication extends WebApplication {

	private Locale defaultLocale = new Locale("en");
	private List<Locale> supportedLocales;

	public I18nTestApplication() {
		List<Locale> locales = new ArrayList<Locale>(1);
		locales.add(getDefaultApplicationLocale());
		locales.add(new Locale("de"));
		locales.add(new Locale("es"));
		locales.add(new Locale("de","AT"));
		supportedLocales = locales;
	}
	
	@Override
	protected Locale getDefaultApplicationLocale() {
		return defaultLocale;
	}

	@Override
	protected List<Locale> getSupportedApplicationLocales() {
		return supportedLocales;
	}

	@Override
	public ViewController<?> getViewControl(String uri) {
		ViewController<?> viewControl =  super.getViewControl(uri);
		Context.getContext().addDebugMessage("user locale: '"+Context.getContext().getUserContext().getPreferredUserLocale()+"'");
		Context.getContext().addDebugMessage("app locale: '"+getDefaultApplicationLocale()+"'");
		Context.getContext().addDebugMessage("current locale: '"+Context.getContext().getCurrentLocale()+"'");
		Context.getContext().addDebugMessage("I18N: '"+uri+"' = "+viewControl);
		return viewControl;
	}

}

Localize your controllers

In this example we use Openbakery Translation to translate the Strings in our controller, of course you can use any method you want here (for example Resource Bundles).

org.jsxp.test.i18n.web.IndexXhtmlController

package org.jsxp.test.i18n.web;

import org.jsxp.framework.Context;
import org.jsxp.test.i18n.web.generated.IndexXhtmlControllerGenerated;

import static org.openbakery.translation.Translation.*;

public class IndexXhtmlController extends IndexXhtmlControllerGenerated<Object> {

	@Override
	public void execute() throws Exception {
		if("es".equals(Context.getContext().getCurrentLocale().getLanguage())) {
			setVariableGreetings("Hola");
			getElementContent().setValue("Your language is not yet fully supported, sorry...");
		} else {
			setVariableGreetings(translate("Hello"));
		}
	}
	
}

But what if a locale has a completely different business logic than the default? Simple solution: Just implement another controller, and place it in a package under the default web package. The package name has to be the locale name:

org.jsxp.test.i18n.web.de_AT.IndexXhtmlController

public class IndexXhtmlController extends org.jsxp.test.i18n.web.IndexXhtmlController {
	@Override
	public void execute() {
		setVariableGreetings("Servus");
	}
}