Skip to content

Files

Latest commit

ab05d8e · Feb 20, 2025

History

History

po

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Translations in MusicBrainz
===========================

This is a short introduction to i18n inside of MusicBrainz

We want MusicBrainz server to have state of the art localizing. This
means using gettext on the one hand and Launchpad's translation
service on the other. Sadly enough, TemplateToolkit's templates are
currently only localizable properly using perl's own maketext
framework, which generates non-standard plural forms in gettext's .po
files which are in turn not translatable using standard gettext tools.

Therefore, we will need to implement some custom solution and give it
back to the community afterwards.

To accomplish that we'd need a two step solution:

1. Prepare the code base for localization.

This means writing localization routines and bringing our strings into
shape for translation (that is, marking them appropriately). No
translations would be prepared at this step, the system would still
work in English, but introducing translations would be a matter of
including some .po files. This is currently implemented as
Catalyst::Plugin::I18N::Gettext, which uses Locale::TextDomain.

2. Implement automatic .pot generation.

This has been the tricky part so far: xgettext.pl (from maketext) which
is capable of doing so, generated non-standard plurals, and xgettext
(from GNU gettext) doesn't parse TemplateToolkit's syntax
properly.

Previously, an ad-hoc .pot generation method had been implemented
which required Babel (http://babel.edgewall.org) and TemplateToolkit's
Python port (checkout from svn://svn.tt2.org/tt/Template-Python/trunk)
to work. In the end, that ad-hoc implementation has been replaced by a
perl-based one, thus removing the need for Template-Toolkit Python
port and Babel. Still, the implementation is to be considered ad-hoc
and experimental, but works in our case.

However, this is not really a sane implementation. Since
Locale::Maketext::Lexicon lacks support for proper gettext
pluralization and changing that might lead to incompatibility problems
in the Perl community. Therefore, a TemplateToolkit parser should be
introduced to GNU gettext. This is probably the sanest way of all
possible, since we could use gettext without drifting too far apart
from the canonical implementation. The implementation might be pretty
straight-forward except that it will have to be implemented in C. A
bison parser could help eventually. One problem might be that gettext
might be slow to appear in distributions (compared to CPAN) but it
would only take a statically linked binary to generate the .pot file
once the templates change and this will probably happen only
every so often.

Preparing the code
==================

Assuming that the code itself doesn't have any translatable strings
(which is to re-check), we'd only have to translate TemplateToolkit's
templates, some blobs in the database and probably some JavaScript.

TemplateToolkit
---------------

Every string in a template should be marked as localizable, this can
be done with an l()-function:

[% WRAPPER "layout.tt" title="l('Welcome to MusicBrainz!')" %]

If some interpolation is needed, it should be implemented with a named
parameter and a parameter hash:

[%- l('{entity} has no aliases.', {entity => entity_link(entity)}) -%]

[% l('You may proceed to <a href=\"{url}\">your user profile</a>,
      or maybe you want to {edit_link}', url => c.uri_for('/user/profile
     '), edit_link => doc_link("How_Editing_Works", l("start editing!"))
%]

Plurals are done with an ln()-function:

[% l('{num} relationship not shown.', '{num} relationships not shown', n, {num => n}) %]

(proper syntax: ln(english_singular, english_plural, number, parameter_hash))

**Warning**: Plural forms only apply to enumerable entities, that is, "I
  have X apples" should be localized with ln(), but "I have apples"
  should use l().

Perl code
---------

To be written.

TODO: check javascript translation needs
TODO: check database's translation needs