Die Arbeit mit gettext

  1. Erzeugung der Übersetzungsverzeichnisstruktur (Hmpf)
  2. Portable Object files
  3. Translation Domain
  4. Using Translator in PHP
  5. Variable interpolation

gettext™ ist der GNU-Standard für das Internationalisierungs- und Übersetzungssystem. Es kann im Zusammenspiel mit PHP benutzt werden und wird von PHPTAL unterstüzt.

Die Benutzung von gettext™ ist einfach, aber Sie sollten einige Tests durchführen, um sicherzustellen, daß auf ihrem Rechner alles richtig zusammenspielt.

PHP muß mit dem --with-gettext Schalter kompiliert werden. Näheres dazu findet sich in der PHP-Dokumentation.

Mit dem folgenden Stückchen Code können Sie ihre PHP-Installation daraufhin prüfen:


//
// test if gettext extension is installed with php
//

if (!function_exists("gettext"))
{
    echo "gettext is not installed\n";
}
else
{
    echo "gettext is supported\n";
}

Erzeugung der Übersetzungsverzeichnisstruktur (Hmpf)

Die PHP-gettext™-Erweiterung verlangt nach einer bestimmten Verzeichnisstruktur, die die Übersetzungsdateien enthält.

/path/to/your/translation_root/en_US/LC_MESSAGES/
/path/to/your/translation_root/en_GB/LC_MESSAGES/
/path/to/your/translation_root/fr_FR/LC_MESSAGES/
/path/to/your/translation_root/es_ES/LC_MESSAGES/
… and so on …

Die Sprachkode besteht aus zwei Zeichen, die die eigentliche Sprache (fr, de, it, …) und zwei Zeichen, die das Land (FR, CH, DE, IT, …) festlegen.

Das Verzeichnismuster sieht so aus:

<path_to_where_you_want>/<ll_CC>/LC_MESSAGES/

Portable Object files

PO-Dateien sind Klartextdateien, die die Übersetzungen enthalten. Sie können sie problemlos händisch editieren.

minimalistisches po-Beispiel (en_US/LC_MESSAGES/mydomain.po):

msgid ""
msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"

msgid "Simple test"
msgstr "A small sentence in english"

Einmal bearbeitet, muß jede PO-Datei indiziert werden:

msgfmt mydomain.po -o mydomain.mo

Dieser Aufruf funktioniert nur, wenn Sie die gettext™-Werkzeuge auf ihrem System installiert haben.

Hierdurch wird eine MO-Datei (machine object) erzeugt, in der Ihre Übersetzungen für einen schnellen Zugriff indiziert vorliegen.

Nun müssen Sie diese Datei in die anderen gewünschten Sprachen übersetzen.

Minimalistisches PO-Beispiel (fr_FR/LC_MESSAGES/mydomain.po):

msgid ""
msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"

msgid "Simple test"
msgstr "Une petite phrase en français"

Auch diese Übersetzungsdatei muß indiziert werden:

msgfmt mydomain.po -o mydomain.mo

Translation Domain

The domain is matched against your translation file names. In above examples we used 'mydomain' as domain name.

You can have more than one domain for the same application, it can enhance gettext™'s performance to split your application translations in more than one file.

Using Translator in PHP

<?php
require_once 'PHPTAL.php';
require_once 'PHPTAL/GetTextTranslator.php';

try {
    $tr = new PHPTAL_GetTextTranslator();

    // set language to use for this session (first valid language will
    // be used)
    $tr->setLanguage('en_GB.utf8', 'en_GB');

    // register gettext domain to use
    $tr->addDomain('mydomain', '/path/to/your/translation_root');

    // specify current domain
    $tr->useDomain('mydomain');

    $tpl = new PHPTAL('mytemplate.xhtml');

    // tell PHPTAL to use our translator
    $tpl->setTranslator($tr);

    // output translated template
    echo $tpl->execute();
}
catch (Exception $e){
    echo $e;
}

If you need to translate some other text, that is not in the template (e.g. plaintext e-mail message), you can reuse PHPTAL's translator:

$tr = $tpl->getTranslator();

$subject = $tr->translate("Registration information");

$tr->setVar("user",$username);
$message = $tr->translate("Dear ${user}, thanks for registering!");

mail($email, $subject, $message);

If you're using PHPTAL's standard gettext™ translator, you can use gettext() too.

Variable interpolation

The I18N Namensraum allows some variable interpolation in your translations.


# english
msgid "welcome"
msgstr "Welcome ${name} you have ${n} mails!"

# french
msgid "welcome"
msgstr "Bienvenue ${name} vous avez recu ${n} messages!"
        

A template can use this interpolation as follows:


<span i18n:translate="welcome">
  Welcome
  <span i18n:name="name" tal:replace="user/name"/>
  you currently have
  <span i18n:name="n" tal:replace="user/unreadeMails"/>
  unread messages!
</span>
        

Because i18n:translate contains a value 'welcome', the template data will be ignored and the message given by gettext™ will be used instead.