WordPress Plugins übersetzen mit gettext, po und pot Dateien

Es gibt eine Reihe von Beschreibungen zum Thema wordpress Plugin Übersetzungen. Hätte ich das gewusst als ich anfing ein Plugin zu entwickeln, dann hätte ich es gleich mit gettext, dem wordpress codex entsprechend umgesetzt. Da ich diese Kenntnisse nicht hatte, habe ich mir selbst beholfen und einfach alle Übersetzungen in einem Array abgelegt und je nach ausgewählter Sprache, das Array mit den richtigen Übersetzungen gefüllt.Das sieht dann beispielsweise so aus:

function set_translation($LANGUAGE)
{
$tl=array();
// Translated Labels
$tl['time'] = "time";
....
if ($LANGUAGE=="de"){
// Translated Labels
$tl['time'] = "Zeit";
....
}
return $tl
}

Die Funktion set_translation wird einfach mit dem Ländercode aufgerufen und schon erhält man ein array mit den gewünschten Übersetzungen. Um die Übersetzung aufzurufen verwendet man einfach

echo $tl['time'];

Ein solches Konstrukt auf die gettext Vorgehensweise anzupassen macht ein bisschen Arbeit. Aber immerhin hinterher, ist es einfacher zu pflegen, denn man kann einen der verfügbaren gettext Editoren verwenden (z.B. poedit) . Und es ist der Standard. Aber vor allem soll es schneller sein (wirklich verifiziert habe ich das noch nicht).

wordpress sieht für die Übersetzung von Programmteilen zwei Funktionen vor, die _e() und die __() Funktion. Erstgenannte gibt den übersetzten Text direkt aus (e = echo), die zweitgenannte liefert den übersetzten Text zur weiteren Verwendung zurück. Beide Funktionen erlauben neben dem ersten Parameter für den eigentlichen Text, einen zweiten Parameter zur Angabe der Textdomain, so eine Art separater Bereich oder Klasse von Übersetzungen für einen bestimmten Programmteil (oder ein Plugin). Durch die Textdomain kann man ausschließen, andere Übersetzungen zu überschreiben oder selbst überschrieben zu werden.

So sieht das dann aus:

$a = __("time","meinedomain"); echo $a;
_e("time","meinedomain");

Beide Zeilen bewirken übrigens das Gleiche.

Um aus den mit den Funktionen _e und __ arbeitenden PHP Dateien eine POT Datei (also ein Template für die Übersetzung, mit allen verwendeten String drin) zu erzeugen bedient man sich xgettext.

Der Aufruf

 xgettext -L PHP -k --keyword=_e  --keyword=__ --from-code=latin1 --default-domain=meineDomain --output=meinTemplate.pot *.php

generiert das Template.

Um jetzt die Übersetzungen einzupflegen kopiert man am einfachsten das Template in eine Datei mit dem jeweiligen ISO-Code der gewünschten Sprache, z.B. de_DE.po für deutsch oder sv_SE.po für Schwedisch.

Diese Datei editiert man dann mit einem gettext Katalog Editor, wie oben erwähnt verwende ich poedit.

In einem letzten Schritt wandelt man jetzt diese Textdatei in einen binären gettext Katalog.

Dies geschieht mit dem Befehl msgfmt. Beispielsweise:

msgfmt  -o de_DE.mo de_DE.po

Wer jetzt schon mal ausprobiert, ob es funktioniert wird feststellen, das der Katalog noch nicht herangezogen wird und daher noch gar nichts übersetzt wird. Dazu muss man WordPress noch mitteilen, das der Katalog zu laden ist.
Wordpress bietet dafür die Funktion load_plugin_textdomain(‚mydomain‘) an. Der Parameter ‚mydomain‘ gibt den in den _e() und __() Funktionen verwendeten Domänennamen an. Nach dieser Anpassung sollte es dann auch mit der Übersetzung klappen.

Noch zwei Tipps:

Es soll vorkommen, dass man ein Plugin weiterentwickelt und sich damit auch der Umfang der zu übersetzenden Texte verändert.
Das gettext Paket hat auch hierfür eine Lösung. Mit dem Programm msgmerge kann man ein neues Template (.pot) und eine vorhandene Übersetzung (.po) zusammenführen und das ohne bereits übersetzte Texte zu verlieren.
Der Aufruf

msgmerge -U de_DE.po myinplugin.pot

ergänzt die .po Datei um noch nicht vorhandene Texte.

Wenn man wie ich zunächst mit einer Array Variante gearbeitet hat, so wäre es ehr mühsam alle Textstellen händisch von $tl[…] auf __(…) anzupassen. Es kommen schnell dreistellige Anzahlen von Textstellen zusammen und dieser Weg wäre sehr mühsam.
Um sich zumindest 99% der Arbeit zu sparen, kann man sich des sed und regulärer Ausdrücke bedienen.

	cat myplugin.php | sed 's/$tl\[\(.*\)\]/__(\1,\'\mydomain')/g'

Der sed sucht (s/) nach den Stellen an denen $tl[…] vorkommt und ersetzt diese durch __(…). Die Angabe \1 verwendet den durch \( \) eingegrenzten Teil des Ausdruckes. Ist eher etwas für den fortgeschrittenen Linuxer. Eine gute Dokumentation zu sed findet man unter http://www.nt-nv.fh-koeln.de/pits/regex.html.

Kommentare

  1. Selena Henn:

    Ich habe ein benutzerfreundliche, webbasierte Lokalisierungstool um WordPress Themen zu übersetzen gefunden https://poeditor.com/ Es gibt sogar ein Plugin, das integriert die POEditor API in Ihre WordPress http://wordpress.org/extend/plugins/poeditor/
    Ich empfehle es.

    Antworten

  2. bigu:

    Hallo Hans
    Habe Dir vor langer Zeit (post 69) eine Frage gestellt, habe die Sache dann jedoch nicht mehr verfolgt. Und zwar besteht das Problem nur beim IE mit dem firefox wird das „leere“ Bild nicht angezeigt.
    http://meinedomain/wordpress/multimedia/ecard
    Wie Du unter dem Link siehst, wird beim Seitenaufruf das Vorschaubild korrekt angezeigt und gleichzeitig wird noch ein grosses, leeres Bild geladen. Wie kann ich das leere Bild verhindern?
    Herzlichen Dank für Deine Rückmeldung
    Gruss, Bigu

    Antworten

  3. [asterix]:

    Danke für die ausführliche Anleitung! Habe damit nun „Twitter Tools“ Übersetzt.

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

:bye: 
:good: 
:negative: 
:scratch: 
:wacko: 
:yahoo: 
B-) 
mehr...
 
ALL-INKL.COM - Webhosting Server Hosting Domain Provider Blogverzeichnis - Blog Verzeichnis bloggerei.de