One of the unique characteristics of Application Express is that it is one of the few development frameworks where the decision to localize and translate an application can be made after the application is actually completed. Because the definition of the application is maintained in meta data in the APEX repository, it's already known in advance which attributes of your application are translatable and which are not.
The process to produce a translated application is pretty straightforward. It's as simple as:
- Seed the translation repository from your existing application
- Export the XLIFF file
- Translate the XLIFF file
- Upload the XLIFF file
- Apply the XLIFF file
- Publish your translated application
The first few translation unit lines of a sample XLIFF file generated from Application Express look like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | < trans-unit id = "S-2-885632848731895778-25721" > < source >Logout < target >Logout</ target > </ trans-unit > < trans-unit id = "S-2-885632950195895779-25721" > < source >Print < target >Print</ target > </ trans-unit > < trans-unit id = "S-2.1-885632848731895778-25721" > < source >Logout < target >Logout</ target > </ trans-unit > < trans-unit id = "S-2.1-885632950195895779-25721" > < source >Print < target >Print</ target > </ trans-unit > < trans-unit id = "S-4-885632364763895772-25721" > < source >Home < target >Home</ target > </ trans-unit > < trans-unit id = "S-4-885632445599895776-25721" > < source >Customers < target >Customers</ target > </ trans-unit > < trans-unit id = "S-4-885632564774895777-25721" > < source >Products < target >Products</ target > </ trans-unit > < trans-unit id = "S-4-885632638841895777-25721" > < source >Orders < target >Orders</ target > </ trans-unit > < trans-unit id = "S-4-885632745057895778-25721" > < source >Charts < target >Charts</ target > </ trans-unit > |
Each translatable string is included as a 'trans-unit' in the XLIFF file. The last two elements of each translation unit ID are the meta data ID and the application ID. For example, in translation unit with id S-4-885632445599895776-25721, the meta data ID is 885632445599895776 and the application ID is 25721. (S-4 is an internal code signifying that this is a meta data string and corresponds to the text of a tab).
As I've discussed in a recent blog post about saved Interactive Reports, I explained how the internal meta data IDs "shift" or are recalculated when importing an application to a new ID. And this has presented problems for those customers who make use of the translation facilities of Application Express. Because the meta data IDs are a part of the XLIFF translation unit IDs, when those IDs change, the existing XLIFF files for the original application cannot be used against a new version of the application imported elsewhere as a new application ID. What a dead end!
I have authored an APEX application which helps customers overcome this problem. You can run the hosted version of the XLIFF Transformation application which is running in my workspace on apex.oracle.com, or you can download a copy of it and run it on your own APEX 4.0 or later instance. You need to provide 3 things when running this application:
- The original XLIFF file
- The application ID of the new application
- The offset value between the two applications
To compute #3, I'll refer you to this same blog post where I give a couple examples how to determine the offset value.
The logic is really quite simple. After importing the application and installing the supporting objects, only 3 objects will be created - a table named XLIFF_FILES, a trigger on this table, and a small PL/SQL package named XLIFF_TRANSFORM. The PL/SQL package parses the XML file and uses some XDB APIs to replace certain elements of the XML file. By exploiting the native functionality of the database, this was really quite easy to write. For anyone who says the Oracle database is only good for "persisting data", I say smoke this!
This isn't my ideal solution. In a future release of Application Express, I'd like to make it as simple as choosing to include your translations in your application export file, and they move around with you. As the metadata gets transformed on a new import, so do the translations. But until then, this solution can be used.