[Catalyst] Localisation

Guido Flohr guido at imperia.bg
Tue Oct 18 23:02:47 GMT 2011


Duncan Garland pointed me to this discussion.  Please don't flame me if
I missed some obvious points from the previous discussion.  Pipermail
messed up all mails encoded in base64.  See for example

I didn't bother to decode them, sorry.

I am the author of libintl-perl aka Locale::TextDomain, and of the Perl
backend of GNU gettext.  3-4 years ago I have experimented with
Catalyst, always with - it's my hobbyhorse, after all - i18n/l10n in
mind.  I haven't touched Catalyst since then; if I missed any recent
developments, sorry again, and correct me.

For obvious reasons I used GNU gettext for localisation for these
experiments, with minimal pain.  For the Perl side (model and
controllers) I just used libintl-perl, and it is a piece of cake, it
just works.  For the views I wrote a plug-in for Template Toolkit which
exported the gettext API into TT templates.  If anybody volunteers to
maintain that plug-in, drop me a line.  I didn't upload it to CPAN
because I felt that I'm not good enough with TT and Catalyst.  But it
basically works.

When you endeavour to internationalize a web project nowadays, the
runtime-aspect is negligible.  It doesn't matter how you look up
translations for messages, even with a gettext implementation without
contexts or the ngettext plural API, even with catgets.  In reality, you
can always workaround those run-time problems.

The real problems are:

1) You must be able to create translation files that are accepted by
professional translators.  Most professional translators for software
expect formats used by applications for MS-DOS/Windows.  More and more
translators accept PO files.  In that other world, where unicorns
excrete rainbows, sunshine and butterflies, they will also happily
subclass from your localization handle.

2) Except for one-shot projects, your translation files should be
mergeable (mergable?).  Portable object (PO) files are pretty much
mergeable.  Some proprietary frameworks maybe offer similiar
functionality.  But I'm only positive for PO files.

3) In an MVC environment, every translatable message in a model or
controller is a potential bug or flaw, at least according to yours
truly.  Views are nowadays template based.  The challenge is to extract
messages from your templates.  With Perl (Python, Ruby, ...) this is
actually easy-going because you can usually (ab)use your template
processor for extracting messages, dump it into a .pot file, (msg)merge
it with your old po file, and your translators are happy, see 1).

4) At run-time: GNU gettext selects translations based on the currently
selected locale, on “the currently selected locale”.  That makes sense
for desktop applications but not for client-server applications, leave
alone threaded applications.  Switching locale is never thread-safe and
potentially slow.

I hope that I will be able to improve the situation a little bit with
libintl-perl 2.x.

As far as 4) is concerned, I plan to provide functions that look up
translations without switching locale.  Instead, you can provide the
name of a language or even the name of a file containing translations.

The show stoppers are modules/libraries/external applications that use
the native gettext framework, most notably the system libc.  They will
still select the translation based on the user locale, resulting in ugly
language mixes, and even uglier charset mixes.  Actually, in a web
application you should strive to hide such messages from the user, for
usability or merchantability.  Yet, this is an open issue.

For 2), with libintl-perl 2.x you will have functions that can read,
filter, and write PO  (and also MO) files.  If you want to gettextize
your proprietary best-template-system-in-the-world-format files, just
write an extractor for that format, feed it into
Locale::Catalog::Format::PO, write a .pot file, and msgmerge it with the
other .pot files from your project.

You can follow the progress here:


Check out the POD of lib/Locale/Catalog/Format/PO.pm,
lib/Locale/Catalog/Format/MO.pm and lib/Locale/Catalog.pm as starters.

Please don't expect any production code from the above sources before
the end of the year.

Империя ООД                         | Imperia OOD
ул. „Княз-Борис-I“ № 86, София 1000 | ul. "Knyaz-Boris-I" № 86, Sofia

More information about the Catalyst mailing list