How to internationalise a product
From OpenQuote
Contents |
OpenQuote has good built in support for the internationalisation of products. This means it is possible for users to see numbers and currency amounts displayed in a format that they are used to, and for the text of questions and answers to be displayed in their language.
Numbers and financial amounts
Without any configuration you will find that currency amounts and numbers displayed and entered during the quotation process are formatted to match the users locale. So, for example, when a user in the UK sees 1,000.00; a user in Europe will see 1.000,00. Monetary amounts work similarly. A value of 1000 US Dollars will display as $1,000 to a user in the US and as US$1,000 to a user in Canada. Any product that you develop will benefit from this without any special configuration being needed.
Text, questions and labels
The second important area covered by internationalisation is the translation of text displayed to the user. This covers the text that appears in labels and questions, and the text on buttons, drop down lists etc.
As with most things in OpenQuote, the language translations used by a product are inherited from it's parent product. They may also be extended or overridden within the product too. The Base product defines a set of translations that are inherited by all products.
The translation files are held in the CMS system along with all the other product information. You can find the Base product translations in Product/AIL/Base/Translations.xml. If you open that file, you'll see something like this:
<translations defaultLanguage="en" xsi:type="java:com.ail.core.language.Translations" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <translation language="en"> <element key="i18n_?">?</element> <element key="i18n_Yes">Yes</element> <element key="i18n_No">No</element> <element key="i18n_next_button_label">Next</element> <element key="i18n_previous_button_label">Previous</element> <element key="i18n_quit_button_label">Quit</element> <element key="i18n_saved_quotations_confirm_button_label">Confirm and Pay</element> <element key="i18n_saved_quotations_requote_button_label">Requote</element> <element key="i18n_proposer_details_postcode_label">Postcode</element> ... </translation> <translation language="en_US" extendsLanguage="en"> <element key="i18n_proposer_details_postcode_label">Zipcode</element> </translation> <translation language="de" extendsLanguage="en"> <element key="i18n_Yes">Ja</element> <element key="i18n_No">Nein</element> <element key="i18n_next_button_label">Weiter</element> <element key="i18n_previous_button_label">Zurück</element> <element key="i18n_quit_button_label">Beenden</element> <element key="i18n_quote_button_label">Holen ein Angebot</element> <element key="i18n_saved_quotations_forgotten_password_message">Passwort vergessen?</element> <element key="i18n_saved_quotations_confirm_button_label">Bestätigen und zahlen</element> <element key="i18n_saved_quotations_requote_button_label">Requote</element> <element key="i18n_proposer_details_postcode_label">Postcode</element> ... </translation> </translations>
As you can see, three translations are defined here: "en" (English), "en_US" (US English) and "de" (German). The first line in the file selects "en" as the defaultLanguage. This means that where the system cannot find a language to match the user's locale, it will use the definitions held in the "en" section.
The "language" attribute in each <translation> defines the locale that the translation applies to. You can find a complete list of legal locales here: ISO639. The <translation> may also define extendsLanguage. If it does, and the system cannot find a translation that it needs it will use the one defined in the translation for the extendsLanguage. For example, in the above the translation for "en_US" only defines Zipcode, but as it has an extendsLanguage="en" it will pull all of the other definitions from the "en" section.
Each <element> maps a key which the UI widgets use, and products may use, to the piece of text which should be displayed. So, for example when a product defines an attribute of format "yesorno", the UI is coded to use the values from the keys "i18n_Yes", "i18n_No", and "i18n_?" to render the drop down list (or radio buttons) on the UI. In an "en" locale, this will result in a list containing "?", "Yes", and "No" being displayed. In a "de" locale the same question will display "?", "Ja", and "Nein".
Adding translations to the Base product
Modifying the system wide translations defined in the Base product is simply a case of editing the file Product/Base/Translations.xml, making the necessary changes and checking-in the change. The changes will immediately become active and you can test them in the product manager's sandpit tab.
To add a whole new language, the process is very similar. You edit the same file, and simple add a new <translation> section. The easiest approach is to copy the "en" section, change the locale and replace the text within each element with the appropriate text for your language. The keys, naturally, must remain as they are.
Adding translations to a product
Products can define their own Translations.xml file in exactly the same format as discussed above. Generally, you will want your product's translations to work in addition to those defined in the Base product so that you can add the translations that your product needs by also rely on those already defined in the Base product.
To do this, you would add the following to your product's Registry.xml.
<configuration ...> ... <type name="Translations" builder="CastorXMLBuilder" singleInstance="true" key="com.ail.core.language.Translations"> <parameter name="Extends">super.Translations</parameter> <parameter name="Url">./Translations.xml</parameter> </type> ... </configuration>
If you did want to use just the translations defined in your product, and ignore those defined in the Base, you would add this to the Registry.xml instead:
<configuration ...> ... <type name="Translations" builder="CastorXMLBuilder" singleInstance="true" key="com.ail.core.language.Translations"> <parameter name="Url">./Translations.xml</parameter> </type> ... </configuration>
Using translations from a PageFlow
To use translations from within a PageFlow you simply refer to the key of the translation in the label or title tag of the page element rather than defining the text itself.
So, for example, if you had a "Next" button defined in your pageflow and you e wanted to internationalise the label that appears on it, you would replace the "Next" label with the i18n_ key from the Translations.
So you would replace this:
<commandButtonAction label="Next" destinationPageId="CollectPaymentDetails"/>
with this:
<commandButtonAction label="i18n_next_button_label" destinationPageId="CollectPaymentDetails"/>
