Localise your forms

Building dynamically localised applications is a real cinch with XForms. This article describes one approach to doing it.

Let's assume that you already have an application that you want to localise. For the sake of this demonstration, we'll use a simple form that requests a user's name:

  1. <xf:model>
  2. <xf:instance id="instData">
  3. <data xmlns="">
  4. <name1>Phil</name1>
  5. <name2>Booth</name2>
  6. </data>
  7. </xf:instance>
  8. </xf:model>
  9.  
  10. <xf:input ref="instance('instData')/name1">
  11. <xf:label>First name</xf:label>
  12. </xf:input>
  13.  
  14. <xf:input ref="instance('instData')/name2">
  15. <xf:label>Surname</xf:label>
  16. </xf:input>
Phil Booth First name Surname Prénom Nom en First name Surname

Now let's say that you want to translate this application into French. What steps do you need to take to achieve that?

The first thing that you must do is move all of your labels into their own instance:

  1. <xf:instance id="instLabels">
  2. <labels xmlns="">
  3. <locale id="en">
  4. <name1>First name</name1>
  5. <name2>Surname</name2>
  6. </locale>
  7. </labels>
  8. </xf:instance>

You can see that the labels have been placed inside a container that identifies their locale. Storing them in a structure like this makes it easy to add translations for as many different locales as neccessary. Here is the same instance, with translations added for the French locale:

  1. <xf:instance id="instLabels">
  2. <labels xmlns="">
  3. <locale id="en">
  4. <name1>First name</name1>
  5. <name2>Surname</name2>
  6. </locale>
  7. <locale id="fr">
  8. <name1>Prénom</name1>
  9. <name2>Nom</name2>
  10. </locale>
  11. </labels>
  12. </xf:instance>

With the labels instance in place, the next thing that's required is a way for the user to select their preferred locale. A select1 control is a good candidate for doing that. First, an instance is required to store the current locale selection:

  1. <xf:instance id="instState">
  2. <state xmlns="">
  3. <locale>en</locale>
  4. </state>
  5. </xf:instance>

Then, a select1 control is needed to allow the user to make that selection:

  1. <xf:select1 ref="instance('instState')/locale" appearance="full">
  2. <xf:item>
  3. <xf:label>English</xf:label>
  4. <xf:value>en</xf:value>
  5. </xf:item>
  6. <xf:item>
  7. <xf:label>Français</xf:label>
  8. <xf:value>fr</xf:value>
  9. </xf:item>
  10. </xf:select1>

All that is left now is to link up the label elements from the input controls to the labels instance, indexed by the id of the currently selected locale. The XForms model will then automatically ensure that the input labels get refreshed appropriately, every time the user updates their locale:

  1. <xf:input ref="instance('instData')/name1">
  2. <xf:label ref="instance('instLabels')/locale[@id = instance('instState')/locale]/name1" />
  3. </xf:input>
  4.  
  5. <xf:input ref="instance('instData')/name2">
  6. <xf:label ref="instance('instLabels')/locale[@id = instance('instState')/locale]/name2" />
  7. </xf:input>
English en Français fr
AttachmentSize
enfr.png16.82 KB

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

The problem with this

The problem with this approach is complex XPath expressions in the ref attributes as well as loading all language labels even though they might not be needed at all.

In my opinion, a more elegant solution would have a ui-instance containing only labels of the selected language. If the UI language is changed, then the content of that instance will be replaced (using xforms:submission) with the labels of the newly selected language. This approach solves both issues pointed above.

Kind regards

-Markku

Yes, it's a good example of

Yes, it's a good example of XForms potential.

Let me give you small comments about it :

  • "instState" instance should be initialized at "en" (and it is what you did in the form looking at the source code!)
  • please type "Français" instead of "Française" ;-)
  • shouldn't XForms elements be rendered as inline elements ? (it sounds like a regular mistake for "young" XForms implementations to use block elements : XSLTForms and EMC Formula also had this problem in previous versions ;-) )

Thank you again!

-Alain
agenceXML
XSLTForms
Bordeaux, France

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.