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

..
May 11, 2021
Jul 3, 2024
Nov 2, 2023
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 18, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Nov 17, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jan 8, 2025
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Aug 31, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jul 21, 2024
Jun 27, 2024
Jun 27, 2024
Jan 11, 2025
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jan 7, 2025
Jul 3, 2024
Mar 6, 2023
Jun 27, 2024
Nov 17, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jan 7, 2025
Jul 3, 2024
Jul 3, 2024
Sep 15, 2024
Sep 24, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Aug 6, 2024
Sep 3, 2024
Jul 3, 2024
Jul 3, 2024
Sep 1, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jan 21, 2025
Dec 2, 2024
Jul 3, 2024
Jul 3, 2024
Dec 15, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Jul 3, 2024
Feb 9, 2025
Jan 7, 2025
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Feb 16, 2025
Oct 21, 2024
Aug 31, 2024
Aug 31, 2024
Dec 15, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Aug 31, 2024
Feb 20, 2025
Jan 7, 2025
Nov 17, 2024
May 23, 2024
May 23, 2024
Sep 25, 2024
May 23, 2024
May 23, 2024
May 23, 2024
Sep 25, 2024
Sep 25, 2024
Sep 25, 2024
Jul 23, 2024
Sep 25, 2024
May 23, 2024
May 23, 2024
May 23, 2024
May 23, 2024
May 23, 2024
May 23, 2024
May 23, 2024
May 23, 2024
Aug 6, 2024
Nov 28, 2024
Sep 25, 2024
Sep 25, 2024
Jun 14, 2024
May 23, 2024
Aug 6, 2024
May 23, 2024
May 23, 2024
May 23, 2024
Sep 25, 2024
Oct 21, 2024
Sep 25, 2024
May 23, 2024
Dec 15, 2024
May 23, 2024
May 23, 2024
May 23, 2024
May 23, 2024
May 23, 2024
Sep 25, 2024
Sep 25, 2024
May 23, 2024
Feb 20, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 13, 2025
Jan 7, 2025
Jan 7, 2025
Jan 25, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 12, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Jan 7, 2025
Feb 9, 2025
Jan 21, 2025
Jan 7, 2025
Jul 10, 2024
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Dec 22, 2014
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Dec 22, 2014
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 18, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 18, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Nov 17, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Aug 31, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Aug 6, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Aug 31, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Dec 15, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jun 27, 2024
Jan 12, 2025
Jun 27, 2024
Jul 21, 2024
Jun 27, 2024
Jan 21, 2025
Jan 7, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 18, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Feb 20, 2025
Mar 10, 2020
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