Forum OpenACS Improvement Proposals (TIPs): TIP #83 (Reopened): I18N methods for short strings (esp. pretty_names and labels)

The purpose of this TIP is to agree on the proposed method to deal with I18N of short strings like pretty_names and labels for dynamic data.

Dynamic data is generated in a couple of places.

  • AMS (dynamic attributes, relationships, options)
  • Dynamic Types
  • Group creation
  • Role creation
  • ....
The methodology proposed suggests that developers transform strings like "pretty_name" or "group_name" or "label" before insertion into the database using the lang::util::convert_to_i18n function that does the following:
  • It creates a message_key in the "placeholder" package "acs-translation" that stores the actual pretty_name
  • It returns the message_key in the "# message_key#" fashion.
This message_key returned from convert_to_i18n should then be inserted into the database instead of the pretty name.

By approving this TIP you agree to add a dependency from acs-lang to acs-translations, so we have the placeholder package in place.

Discussed in OCT meeting on 16 Aug 2005. We were not clear on the purpose of this change. Please provide a more detailed explanation, including an example of how it would be used and what the benefit would be.
You create a group. The group has the name "Malte's Friends". You have an international site. The spanish person should see the group as "Malte's Amigos" and the German one as "Maltes Freunde". This is impossible as of now.

You create a dynamic attribute. It is called "customer". In an international site it is impossible to have the Attribute named "Customer" if you deal with German "Kunden".

In general there are a *LOT* of places where we store a "pretty_name" or a "label" in the database. As the name suggests (pretty_name) this is something that is displayed to the user. Anything that is displayed to the user needs to be I18N, otherwise OpenACS will not be a really international piece of software.

My method (which, due to the fact that the TIP got two yes and no no's within one week is already implemented on HEAD with some packages depending on it) allows you to use the lang::util::convert_to_i18n function to store an internationalized version of the string instead of the string itself. This way you can translate the string. It is smart enought to not I18N a string that is already I18N ready.

The acs-translation package is only a placeholder for the translations, we could store it anywhere. And yes, this package acts as a way to internationlize *content*, though the content it is trying to I18N are short "pretty_names" or "labels", and the TIP only proposes to add the dependency from acs-lang to acs-translations so that lang::util::convert_to_i18n actually works and packages like contacts or acs-subsite can make good use of it.

Jeff mentioned the problem of using the text for the message key generation is not unique. To solve this problem, the call for I18N should be different in that way that you use the unique identifier (e.g. group_name or attribute_id) for the message_key and not simply the text. This can be done the following way:

#groups
set title [lang::util::convert_to_i18n -message_key "group_${group_name}" -text "$group_name"]

set group_id [package_instantiate_object ......]

db_dml title_update "update acs_objects set title=:title where object_id = :group_id"

# ams attributes
set pretty_name [lang::util::convert_to_i18n -message_key "ams_attribute_pn_${attribute_id}" -text $pretty_name]

More notions:

"if the original key is created with a different language, won't there be a problem with mis-matched keys creating a possible huge number of keys that mean the same thing?"

To solve this I will readd the feature to check for the user's locale first and then insert it into the user's locale as well as the system locale.

The insert into the system locale will be in the wrong language, but we need to insert into it due to constraints in acs-lang.

Alternatively we wrote a bablefish soap query, so we could ask bablefish for a translation :)

To register a language key you have to put the language key into a package. Otherwise we'd have to change the datamodell for acs-lang, which I don't want to do.

Therefore I will keep acs-translations as the default storage for attributes and ask in the TIP to have acs-translations approved as a core package (not to mention again that according to TIP rules it had already been approved...)

The idea of Don to use attribute_name.object_id as the identifier for the message key is a good one. Sadly it has the huge drawback that you will have to create the object *before* you define the message key. And as you need to insert the message key along with the creation you are in a chicken and egg problem. Therefore it is up to the package maintainer to make sure the message key will be unique (e.g. using object_type.context_id.attribute_name as the identifier).
Malte,

WHy can't acs-tranlations support be optional? acs-lang should be able to check if acs-tranlations is installed and handle itself accordingly.

You can use use object_id in the message key by pre-generating the object_id. If you are using ad_form this should work since you already have the object_id when you submit. All "object_type" generation prodcedure should accept a pre-generating object_id so I don't see a problem here.

This TIP is already implemented, Yiekes. Well, we did have lengthy discussions on IRC and other places so I think I pleased everyone. But for the sake of the argument, would the OCT on the next meeting *please* discuss this finally. If you reject though, then a lot of procedures are in big trouble 😊.