Since Friday my focus on KnowledgeTree has been translation support for KnowledgeTree. The major items I'm working on are escaping gettext, language plugins, language selection at login, and improving the marking up of strings to be translated.

Gettext has been on my nerves. It's advertised as the one true way to do these things, but it has a number of issues.

Firstly, it's an optional binary module in PHP. That means we only work on systems with this module installed, and we can't reasonably ship binaries with KnowledgeTree.

Secondly, even if installed, certain installations of it don't allow translation without the full localisation for the locale being enabled for the entire machine. This is most obvious on Debian and Ubuntu, where you have to enable the locales you want using locale-gen and friends.

So, even if you have the gettext module in your hosting environment, your hosting provider needs to be convinced to enable the locale for you...

And, a minor niggle for me and language plugins - it needs all the files for the gettext domain to live in the same directory.

Solution? File_Gettext is a PHP library in PEAR that understands the gettext PO and MO file formats. KT already has an i18n abstraction system for templates to use, and swapping over to it was about five minutes work.

This made it rather trivial to support the concept of language plugins. Instead of making sure the user puts the right files in the right place, they follow the standard plugin procedure in KnowledgeTree - unzip into the plugins directory.

While we're doing this, it's rather trivial to add a register of languages added to the system, which allows for the language to be chosen at login and set in a cookie. This is a lot easier than explaining to people how to set their browser to use the language they want in any case.

So, improving translation coverage then. This was remarkably easy in the end - I just wrote a replacement i18n class to override the translation of words. Instead of reading from a file, the words are put through a filter to mark them on the screen - each word has a period (.) placed before it, and an apostrophe (') after it. This makes it rather obvious if a phrase is not translated.

Here's the code - it won't work perfectly on KT 3.0.0 because plugin ordering isn't in there, but you'll get the idea at least:

<?php

class XTransPlugin extends KTPlugin {
    var $sNamespace = "xtrans.plugin";
    var $iOrder = -30;

    function setup() {
        $oReg =& KTi18nRegistry::getSingleton();
        $oReg->_ai18ns['knowledgeTree'] =& new XTrans;
    }
}

class XTrans {
    var $bNotEmpty = true;

    function xtranslate($sContents) {
        $aWords = split(' ', $sContents);
        $aRet = array();
        foreach ($aWords as $sWord) {
            $aRet[] = sprintf(".%s'", $sWord);
        }
        return join(' ', $aRet);
    }

    function gettext($sContents) {
        return $this->xtranslate($sContents);
    }
}

$oPluginRegistry =& KTPluginRegistry::getSingleton();
$oPluginRegistry->registerPlugin('XTransPlugin', 'xtrans.plugin', __FILE__);
?>