Tuesday, March 10, 2009

Babel in the Trac trunk.

With the Trac 0.11 branch, internationalization and localization are not possible. I do, however, like the approach that are taking to incrementally implementing this feature. In the 0.11 branch, the gettext() function is actually defined in translation.py. Although it doesn't do anything useful in this branch of the software, it is implemented. More importantly, it is used throughout the application. The pipes of the Trac translation architecture have been assembled, they just don't have anything flowing through them yet.

In the trunk version of translation.py, we have something radically different. There is a new TranslationsProxy class. This class is considered a proxy because the original translation functions still exist only now they invoke methods in this class. Here is an illustration of the TranslationsProxy class.



The attributes are as follows.
  • The _current attribute is the current thread of control.
  • The _null_translations attribute is an empty message catalogue.
  • The _plugin_domains attribute is a dictionary that contains locale domains that may be added to the TranslationsProxy in a programmatic way.
  • The _plugin_domains_lock is a threading lock that is acquired when loading
The need for the _current and _plugin_domains_lock attributes arises when activating a locale. The threading lock is acquired while loading plugin translation domains. Once loaded, the lock is released and the translation message catalogue is set as an attribute on the current thread. This allows different threads of control to have different message catalogues.

I really enjoy the way the plugin message catalogues are merged with the existing catalogue in a thread-safe way. Just based on this feature alone I'm very exited about the next major Trac release.

I wonder if some of the other Python web-frameworks out there handle internationalization message catalogue extensibility this way? I'm sure TurboGears doesn't. I've found that having only a single catalogue for my applications to be very limiting.