This document describes how to develop internationalized OpenACS packages.
At this point, we've only covered things that involve the message catalog: Dynamically picking a chunk of text to spit out based on the locale.
Each section below consists on one part about how to write new internationalized packages, and which explains the details of how it works, and then another part that talks about the process for internationalizing existing packages.
The following section will tell you how to deal with localizable text in ADP files, in TCL files, and in APM Parameters.
Internationalizing templates is about replacing human readable text in a certain language with intenral message keys, which can then be dynamically replaced with real human language in the desired locale.
There are 3 syntaxes to choose from: The short, the verbose, and the temporary. Each offer different advantages, but generally, what you want to do is use the short notation for new packages and use the temporary notation for internationalizing old packages, then have the APM translate those into the short notation.
The short: #message_key#
The advantage of the short syntax is that it's short. It's as simple as inserting the value of a variable.
The verbose: <trn key="message_key" locale="locale">default text</trn>
The verbose syntax allows you to specify a default text in a certain language. This syntax is not recommended anymore, but it can be convenient for development, because it still works even if you haven't created the message in the message catalog yet, because what it'll do is create the message key with the default text from the tag as the localized message.
The temporary: <#message_key original text#>
This syntax has been designed to make it easy to internationalize existing pages. This is not a syntax that stays in the page. As you'll see later, it'll be replaced with the short syntax by a special feature of the APM. You may leave out the message_key by writing an underscore (_) character instead, in which case a message key will be auto-generated by the APM.
We recommend the short notation for new package development.
Some parameters contain text that need to be localized. In this case, instead of storing the real text in the parameter, you should use message keys using the short notation above, i.e. #message-key#.
In order to avoid clashes with other uses of the hash character, you need to tell the APM that the parameter value needs to be localized when retrieving it. You do that by saying: parameter::get -localize.
Here are a couple of examples. Say we have the following two parameters, taken directly from the dotlrn package.
Table 4.1.
Parameter Name | Parameter Value |
---|---|
class_instance_pages_csv | #dotlrn.class_page_home_title#,Simple 2-Column;#dotlrn.class_page_calendar_title#,Simple 1-Column;#dotlrn.class_page_file_storage_title#,Simple 1-Column |
departments_pretty_name | #departments_pretty_name# |
Then, depending on how we retrieve the value, here's what we get:
Table 4.2.
Command used to retrieve Value | Retrieved Value |
---|---|
parameter::get -localize -parameter class_instances_pages_csv | Kurs Startseite,Simple 2-Column;Kalender,Simple 1-Column;Dateien,Simple 1-Column |
parameter::get -localize -parameter departments_pretty_name | Abteilung |
parameter::get -parameter departments_pretty_name | #departments_pretty_name# |
The value in the rightmost column in the table above is the value returned by an invocation of parameter::get. Note that for localization to happen you must use the -localize flag.
The locale used for the message lookup will be the locale of the current request, i.e. lang::conn::locale or ad_conn locale.
You're responsible for creating the keys in the message catalog yourself.
Let's deal with dates and times first. The way it works is as follows:
Get the date in ANSI format from the database (YYYY-MM-DD HH24:MI:SS, the time portion is optional). Name the column in the SQL statement something that ends in "_ansi", such as "posting_date_ansi". Example: to_char(posting_date, 'YYYY-MM-DD HH24:MI:SS') as posting_date_ansi
Use the Tcl command "lc_time_fmt" to format the date in pretty format. There are a number of standard, localizable formats to choose from (see below). Example: set posting_date_pretty [lc_time_fmt $posting_date_ansi "%q"]
Use the "*_pretty"-version in your ADP page.
Here's the list of standard date and time formats to choose from:
%c: Long date and time (Mon November 18, 2002 12:00 AM)
%x: Short date (11/18/02)
%X: Time (12:00 AM)
%q: Long date without weekday (November 18, 2002)
%Q: Long date with weekday (Monday November 18, 2002)
If the abbreviations seem a bit strange, it's because they are. Most of them are standardized (see man strftime for example). %q and %Q are our proprietary additions, and 'q' was just about the only letter left in the alphabet.
The command 'lc_fmt_time' allows you to pass in a specific date and time format as well, but please don't, because the whole point is to make it possible for administrators to change date and time formats site-wide based on locales.
Numbers are very easy to format. Just say lc_numeric $value, and it'll format the number using the appropriate decimal point and thousand separator for the locale.
We've created a couple of tools especially for internationalizing the pages of existing packages. The tools can be accessed from the "Manage Internationalization" linked from the package manager page for a package.
The process consists of four steps:
Replace text with tags: This is an automated process, which will try to automatically locate chunks of translatable text, auto-generate a reasonable message key, and surround the text with the temporary <#...#> notation mentioned above.
Manually verify each ADP file. If necessary, you can add additional <#...#> tags, or you can move or remove the ones set by the automated step.
Manually mark up Tcl files, marking up translatable text with the <#...#> notation.
Replace tags with keys: This is an automated process, which will replace the temporary <#...#> notation in both ADP and Tcl files with the appropriate notation for the type of file, and store the text in the message catalog. You need to run the process twice, once for ADP files, and once for Tcl files.
When you run this step, any modified files are backed up in a file with a ".orig" suffix. Those files are never overwritten, though, so the .orig file will always be the original page file, not the second-to-last file. Running this action multiple times is harmless.
The system will auto-generate suggested message keys.
... (WRITE MORE HERE!)
Next step is to internationalize parameters that contain localizable text. See the section Multilingual APM Parameters.