Automatic translation to foreign languages

AngularFaces 2.0 has been designed with foreign language support in mind. JSF always included support for internationalization, but it requires a lot of boilerplate code.

Let's return to the car dealer customer form:

<prime:panel header="Contact information">
  <prime:panelGrid columns="3">
    <prime:inputText value="#{customer.lastName}" />
    <prime:inputText value="#{customer.firstName}" />
    <prime:inputText value="#{customer.dateOfBirth}" />
    <prime:inputText value="#{customer.emailAddress}" />
    <prime:selectBooleanCheckbox value="#{customer.IAgreeToTheTermsAndConditions}" />
  </prime:panelGrid>
  <prime:commandButton value="save" update="angular" action="#{customer.save}" />
</prime:panel>
          

This translates to a nice English version. Well, usually there are a few glitches which can be ignored while your project is in its prototype phase. By the way, you can cure the glitches by providing an English language file. Be that as it may, we chose the bean attribute name with de-camel-casing in mind, so our JSF view renders correct English labels:

To expand to international markets, you'll have to provide translations to the texts. AngularFaces makes it very easy to do so.

Preparing your project

First you have to add the list of supported languages to the faces-config.xml. That's just the same procedure as in traditional JSF programming:

<?xml version="1.0" encoding="utf-8"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
  version="2.0">
  <application>
    <locale-config>
      <default-locale>en</default-locale>
      <supported-locale>de</supported-locale>
      <supported-locale>es</supported-locale>
    </locale-config>
  </application>
</faces-config>          

The next step is to define the language files. It's also the last step :).

The language files resemble the standard JSF language files. They are property files that have to be in the root folder of your classpath. AngularFaces uses a fixed name: it's always "i18n.properties". You can configure that differently (which is good, because you don't have to configure it in the first place).

More precisely, AngularFaces looks for the property files in the same folders JSF does:

The language files

The language files drop several of the constraints give by standard JSF. You can use arbitrary keys. The idea is to simply use the original texts as keys. In a few cases you have to add extra attributes to get rid of ambiguous translations, but in most cases this approach works surprisingly good. The german translation file of our example looks like so:

car dealer - customer contact information=Kontaktinformation
Contact information=Ihre Anschrift
last name=Nachname
first name=Vorname
date of birth=Geburtsdatum
email address=E-Mail-Adresse
i agree to the terms and conditions="Ich habe die AGBs gelesen und akzeptiert."
save=Speichern

You may or may not surround keys and translations with double quotes. Quotes are useful if the texts contain an "equals" sign.

How to modify your JSF file to benefit from the translation files

Now, that's the nice part of AngularFaces: you don't have to do anything to make your JSF files multiligual. Adding the language files and configuring the faces-config.xml is all you have to do to make the contact form look like this:

Which language is rendered depends on the locale setting of the users browsers. Putting it in a nutshell, every customer of yours' will see the JSF page in their language.

Special cases

Currently, there are rougly fourty JSF attributes that are translated automatically:

Even that long list may grow over time, but there's a class of texts AngularFaces can't translate automatically. Simple texts that aren't part of a JSF component are invisible to JSF and to AngularFaces in particular. To solve the problem, there are two tags to force translation: Both tags are synonyms. AngularFaces supports them both because i18n is shorter and used by many, many developers, but <translate> adds more clarity to the code.