Skip to content

Internationalization

Andy Theuninck edited this page Apr 6, 2015 · 2 revisions

Do not mistake this page as implying CORE is fully internationalized and easily translatable. That is not currently the case. This page outlines current support and provides an outline for improvements going forward.

Both Lane and Office use gettext for translations. This requires the php_gettext extension.

Writing Translatable PHP

PHP provides two functions to get the translated version of a string. One is named gettext, the other is simply name _ (underscore). These functions work regardless of whether the php_gettext extension is available.

// instead of this
echo "I am awesome"
// use one of these
echo gettext("I am awesome")
echo _("I am awesome")

I tend to use the underscore version. The only place this is problematic is with class properties. You can't use a function to define a property's value.

class SomeClass
{
    // This is a parse error
    public $description = _('This is an example class');

    // You would need something like this instead:
    public function __construct()
    {
        $this->description = _('This is an example class');
    }
}

Creating / Managing Language Files

This is by no means the only method. Other tools exist for editing these kind of files. Examples are command-line based. Translation files are stored in the locale directory of both Lane and Office (pos/is4c-nf/locale and fannie/locale, respectively).

Gettext can read code files and extract all the translatable strings. These are initially captured in a .pot file. That .pot file is then used to create language-specific .po files.

# create Lane .pot
find ./pos/is4c-nf/ -name '*.php' | xargs xgettext -L PHP -d pos-nf -o pos/is4c-nf/locale/pos-nf.pot --no-wrap -j
# create Office .pot
find ./fannie/ -name '*.php' | xargs xgettext -L PHP -d messages -o fannie/locale/messages.pot --no-wrap -j

The -d option specifies a text domain. Lane uses pos-nf, Office uses messages.

Next, we need to translate the .pot file into a language-specific .po file. The command is this:

# Lane .po file for en_US
msgmerge -U pos/is4c-nf/locale/pos-nf_en_US.po pos/is4c-nf/locale/pos-nf.pot
# Office .po file for en_US
msgmerge -U fannie/locale/messages_en_US.po fannie/locale/messages.pot

The .po file will contain pairs of msgid and msgstr. The msgid is a string that occurs in CORE. The msgstr value is the translation of the msgid string for a particular language. Depending on the language, some or all msgstr values might need to be replaced.

Finally, we need to translate the .po file into a .mo file. The .mo is the binary file that gettext actually uses to look up translations. The .po to .mo command is this:

# Lane
msgfmt -v -o pos/is4c-nf/locale/en_US/LC_MESSAGES/pos-nf.mo pos/is4c-nf/locale/pos-nf_en_US.po
# Office
msgfmt -v -o fannie/locale/en_US/LC_MESSAGES/messages.mo fannie/locale/messages_en_US.po
Clone this wiki locally