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");
}
}