Wie man ein WordPress-Theme lokalisiert

Hier geht es um Lokalisierung oder hübsch kryptisch gesprochen um l10n.

Wer in WordPress ein elegantes Theme oder ein nützliches Plugin verwenden will, dass nur in der Originalsprache des Entwicklerteams vorliegt, kann sich entweder mit dem babylonischen Sprachgewirr abfinden oder sich an die Übersetzung machen. Für die Übersetzung gibt es mehrere Wege. Da wäre z.B. die Möglichkeit die Übersetzung direkt im Code zu platzieren. Leave a Reply würde dann z.B. durch hinterlassen Sie eine Antwort ersetzt. Das wäre die Methode schnell & dreckig kann aber trotzdem manchmal angezeigt sein, so dass wir darüber nicht die Nase rümpfen wollen. Falls der Entwickler sich an den Programmier-Codex für WordPress gehalten hat, dann hat er sicher auch die GNU gettext-Möglichkeiten von WordPress berücksichtigt (mehr zu GNU gettext bei Wikipedia: http://de.wikipedia.org/wiki/Gettext). Ganz allgemein gesprochen ist GNU gettext die Internationalisierungsbibliothek, die zur Entwicklung von mehrsprachigen Programmen genutzt wird. Hat sich der Entwickler also daran gehalten, dann findet sich an den entsprechenden Stellen im Programm-Code, die Texte an den Bildschirm ausgeben, so etwas wie _e('welcome geek','geekertheme') oder auch __('order by','bugtheme'). Dies sind translate()-Funktionsaufrufe, die in wp-includes/l10n.php hinterlegt sind. Der Unterschied zwischen beiden ist, dass _e() die Übersetzung als ECHO an den Bildschirm sendet, während mit __() intern weitergearbeitet wird.

Beispiel:

  1. <h1><?php _e("Page Not Found",'bugtheme'); ?></h1> Hier würde die Übesetzung als Überschrift 1. Ordnung direkt ausliefern.

  2. <?php $prevtop=__("Previous Topic",'bugtheme'); ?> Hier würde die Übersetzung an die Variable zurückgegeben.

Dies ist nützlich zu wissen, denn uns hindert nichts daran, aus <h1>Leave a Reply</h1> im Programm-Code <h1><?php _e("Leave a Reply",'bugtheme'); ?></h1> zu machen. Es ist sicher jedem vom uns schon passiert, dass sich bestimmte Textstellen der Übersetzung verweigern. Hier lohnt auf alle Fälle der Blick in den Programm-Code, ob nicht vielleicht diese Stelle in der Lokalisierungs-Vorbereitung vergessen wurde (1. Möglichkeit, warum eine Übersetzung fehlt).

Zur Syntax der Funktionen (bspw.: _e('erster Teil','zweiter_Teil')): Der erste Teil enthält den zu übersetzenden Text im Stringformat, der zweite_Teil ist optional und wird als Textdomain bezeichnet (die Textdomain soll keine Sonderzeichen enthalten). Die Textdomain könnte also weggelassen werden. Allerdings gilt dann in diesem Fall, dass auf die Lokalisierungsdatei im Ordner wp-content/languages zurückgegriffen wird. Um also die Fäden zusammen zuhalten, sollten die Lokalisierungsdateien im jeweiligen Theme-Ordner bzw. im Plugin-Ordner gespeichert werden.

Falls man sich also ein Theme oder Plugin heruntergeladen hat, lohnt sich ein Blick in den Ordner. Möglicherweise liegt dort bereits eine Datei mit der Endung .pot oder z.B. auch de_DE.po und de_DE.mo.

.pot-Dateien (Portable Object Template )
Sofern es nur eine .pot-Datei gibt, kann dies die Ausgangsbasis für die Übersetzung sein. Die .pot-Datei wird in der Regel nur den Ausgangstext ohne eine Übersetzung enthalten.

.po (Portable Object) und mo-Dateien (Machine Object)
po- und mo-Dateien haben spezielle Formate. In der Regel wird die mo-Datei parallel zur po-Datei erstellt. Die po-Datei muss nicht vollständig übersetzt sein, sondern könnte auch erst teilweise bearbeitet worden sein (2. Möglichkeit, warum eine Übersetzung fehlt). Es könnte natürlich auch die mo-Datei komplett fehlen (3. Möglichkeit, warum eine Übersetzung fehlt). In diesem Fall müssen wir die mo-Datei mittels eines poEditors erstellen. Bevor wir uns mit der Erstellung einer po- und mo-Datei mit poEdit beschäftigen, will ich noch auf drei weitere Möglichkeiten hinweisen, warum eine Übersetzung zu scheitern scheint.

4. Möglichkeit, warum eine Übersetzung fehlt: In der wp-config.php wurde vergessen WPLANG zu definieren. Für deutsch wäre der Eintrag: define ('WPLANG', 'de_DE'); statt define ('WPLANG','');
5. Möglichkeit, warum eine Übersetzung fehlt:
Das Theme hat einen eigenen Translation-Switcher, der möglicherweise auf off steht.
6. Möglichkeit, warum eine Übersetzung fehlt:
Es wurde vergessen WordPress die Textdomain bekannt zu geben. In functions.php muss man die Karten offen legen. Soll also die de_DE.mo aus dem Theme MyBugsTheme geladen werden, dann teile ich dies über die Funktion: load_theme_textdomain(bugstheme) mit (bzw. für Plugins beachte die Besonderheiten: load_plugin_textdomain( $domain, $path_from_abspath, $path_from_plugins_folder )

Sofern es also eine mo-Datei gibt und die besprochenen Fehlerquellen ausgeschlossen wurden, sollte sich das Theme in der Wunschsprache darstellen lassen.

Do it yourself mit poEdit

Um die Lokalisierung selbst in die Hand zu nehmen verwenden wir poEdit. Mit poEdit erstellen wir uns die notwendige mo-Datei (Machine Objects). Als erstes brauchen wir das Werkzeug und den Werkstoff. Unser Werkstoff ist das Theme, dass wir lokalisieren wollen. Wir laden uns also ein frisches und aktuelles Theme herunter und entpacken es. Als nächstes brauchen wir den Editor. PoEdit kann man sich kostenlos von http://www.poedit.net/ herunterladen. Ein weiteres Werkzeug könnte ebenfalls hilfreich sein, falls es Probleme gibt. Es ist der Notepad++, welcher hier kostenlos heruntergeladen werden kann: http://notepad-plus.sourceforge.net/. Der notepad++ kann hilfreich sein, falls poEdit Probleme mit der Windows-Zeilen-Ende-Formatierung (CR+LF) hat, die sich in den themeweiten php-Dateien verbergen. Über die Befehlszeile Bearbeiten >> Zeilenenden >> Konvertiere zu Unix (LF) könnte man dies, für alle Dateien, die _e() und __()-Funktionen enthalten beheben. Im Web werden zahlreiche weitere Probleme besprochen, die im Zusammenhang mit poEdit auftreten könnten. Ich habe für diesen Blog den aktuellen poEdit (Version 1.4.5) benutzt, der sich aus meiner Sicht aber als unproblematisch gezeigt hat. Ich habe quasi die Voreinstellung genutzt und konnte keine Probleme feststellen. Aber wie gesagt, ich werde auch auf mögliche Fallstricke hinweisen.

Wenn poEdit das erste Mal gestartet wird muss man ein paar Einstellungen vornehmen:

Beim Karteireiter EINRICHTEN soll man seinen Namen und seine Mail-Adresse eintragen

Beim Karteireiter EDITOR (mögliche Fallstricke)

a) sollte auf jeden Fall automatisch mo-Datei beim Speichern erstellen ausgewählt sein.
b) das Zeilenende-Format sollte UNIX sein
c) Format existierender Kataloge beibehalten sollte abgewählt worden sein

Beim Karteireiter ÜBERSETZUNGSSPEICHER kann man die Eingaben überspringen

Beim Karteireiter PARSER (mögliche Fallstricke)

Könnte es passieren, dass man den PHP-Parser anpassen muss. Dazu würde man dort PHP auswählen und über BEARBEITEN die Einträge verändern. Dort findet man 6 Formularfelder. Die Vorgabeeinstellungen lauten von oben nach unten:

PHP
*.php
xgettext –force-po -o %o %C %K %F
-k%k
%f
–from-code=%c

Da ich mit diesen Vorgaben keine Probleme hatte, empfehle ich erstmal diese auszuprobieren. Sonst gibt es in älteren Beiträgen noch folgende Einstellungen:

PHP
*.php
xgettext –output=%o %K –language=php %F
–keyword=%k
%f

wobei das letzte Formularfeld frei bleibt (vgl.: http://doku.wordpress-deutschland.org/Erstellen_der_Sprachdatei_mit_poEdit).

Damit wären die Grundeinstellung abgeschlossen!

Jetzt soll ein Katalogprojekt erstellt werden.

Falls es schon Sprach-Kataloge gibt, könnte man über Katalogverwaltung darauf zugreifen. Die Katalogverwaltung bietet einen großartigen Vorteil, denn falls das Theme in seinen sprachlichen Aspekten verändert wurde kann man den Katalog aktualisieren und erhält einen Überblick über hinfällige und neue Textstellen (später etwas mehr darüber).

Über DATEI >> NEUER KATALOG erhält man Zugriff auf die Katalogoptionen.

Im Karteireiter PROJEKTINFO gibt an die „Credentials“ ein. Ich halte die drei ersten Einträge für geboten und die Angabe des Zeichensatzes für notwendig (sofern man im der Übersetzung nicht mit HTML-Entities arbeiten will, also statt ü &uuml; verwenden möchte) er sollte WordPress-like utf-8 sein.

Falls man in die Verlegenheit kommt, dass man im Theme Pluralformen verwendet so würde hier für die deutsche Sprache nplurals=2; plural=n !=1; stehen. Es gibt tatsächlich Länder, die über mehr als zwei Formen verfügen. In diesem Fall muss man sich über die Pluralformen nochmal Gedanken machen. Mir ist aber bis jetzt noch kein Theme begegnet, dass die Pluralformen so steuert, es wird dies doch vielmehr PHP erledigt. Ich empfehle deshalb zunächst auf die Pluralformen zu verzichten (Fallstrick).

beim Karteireiter PFADE trägt man in den Standardpfad lediglich einen Punkt . ein!

Darunter steht ein Listenfeld. Hier können dann die speziellen Pfade eingegeben werden. Da an dieser Stelle die Durchsuchen-Schaltfläche vergessen wurde, empfehle ich über den Explorer den Pfad zum heruntergeladenen Theme zu detektieren. Wenn das Theme also z.B. bei C:\xampp\htdocs\wordpress\wp-content\theme\bugstheme steht, dann ist das der Pfad, den wir in das Listenfeld eintragen müssen. Um dies zu machen klicken wir auf das zweite Ikon von links (auch wenn es als inaktiv geführt wird reagiert es auf den Klick und gibt in der Liste ein Eintragsfeld frei. Dort trage ich den Pfad ein und bestätige den Eintrag mit RETURN (möglicher Fallstrick). Ich kann hier mehrere Pfade einbinden. Der Zweck ist, dass jeder Pfad, den ich hier eingebe separat durchsucht wird.

Beim Karteireiter SCHLÜSSELWÖRTER sind alle translate() Funktionen zu hinterlegen, die im Theme verwendet werden. In der Regel sind dies _e und __. Theoretisch könnten es noch weitere sein (z.B. _c, der dem Übersetzter die Bedeutung im Kontext darlegt (Bspw. Würde: _c('key|password','bugstheme') bedeuten, dass der Begriff im Sinne von Passwort verwendet wird und nicht als Schlüssel übersetzt wird). Mir sind bisher nur die Funktionen _e und __ über den Weg gelaufen. Deshalb geben wir nur die beiden in das Listenfeld ein. Wir machen dies auf die gleiche Art wie bei den Pfaden. In dem wir auf die scheinbar inaktive Schaltfläche NEUER EINTRAG klicken erhalten wir im Listenfeld ein Eintragsformular. In das erste Feld tragen wir: _e ein (einfach nur Unterstrich und kleines e) wir quittieren es mit RETURN (Achtung Fallstrick), bedienen ein weiteres Mal die die scheinbar inaktive Schaltfläche NEUER EINTRAG und geben __ (zweimal Unterstrich) ein. Auch das quittieren wir wieder mit RETURN, damit es auch abgespeichert wird. Wenn wir jetzt auf OK drücken, dann will poEdit eine Datei default.po in das Themeverzeichnis speichern. Wir wollen aber die Datei als de_DE.po abspeichern. Deshalb ändern wir die Vorgabe entsprechen. Nun erledit poEdit seine Arbeit. Der PHP-Parser durchsucht jetzt alle php-Dateien in den angegebenen Pfaden nach den Schlüsselwörtern _e und __ findet dort den ersten Eintrag und erstellt eine Katalogdatei, die wir zum Ausgangspunkt für die Übersetzung machen. In der po-Datei können wir nun mehr nur die Übersetzungspalte verändern. Die Anpassung des Originaltextes bleibt uns in der po-Datei verwehrt. Haben wir mit der Übersetzung begonnen und speichern sie ab, so erstellt uns poEdit automatisch auch eine mo-Datei.

Sind alle Übersetzungen durchgeführt und die po und mo-Datei soll weitergegeben werden, so empfehle ich die po-Datei im notepad++ zu öffnen und alle Einträge die mit:

"X-Poedit- beginnen bis zum Zeilenende zu löschen. Des weiteren sollten auch alle lokalen Pfade gelöscht werden, so dass statt:
#: C:\xampp\htdocs\wordpress\wp-content\theme\bugstheme\404.php:11

nur noch :
#: 404.php:11 steht

Nach dem diese Änderung durchgeführt wurde sollte die de_DE.po nochmal in poEdit geöffnet werden, so dass auf dieser Basis die mo-Datei gespeichert werden kann. Damit sollte dann die Übersetzung problemlos klappen.

Ein aktuelleres Theme auf Textänderungen prüfen

Besonders interessant ist die Möglichkeit Textänderungen im Theme zu übernehmen. Dazu würde man auf DATEI >> KATALOGVERWALTUNG den entsprechenden Katalog (Fallstrick! nicht über DATEI >> ÖFFNEN) auswählen. Über diesen Weg erkennt poEdit Änderungen in den Quelledateien. Wenn ich diese Änderungen übernehmen will, dann prüfe ich über KATALOG >> AUS QUELDATEIEN AKTUALISIEREN die Änderungen. Neue und hinfällige Positionen werden mir angezeigt. So ist eine Anpassung sehr einfach.

Am Rande möchte ich noch auf zwei Alternativen zur Lokalisation von php-Dateien im Allgemeinen und WordPress im Besonderen hinweisen, die ich aber beide noch nicht ausprobiert habe:

News Magazin Theme 640 Lokalisierung de_DE

Das Praxisergebnis po- und mo-Dateien für das Theme news-magazin-640 kann man sich hier herunterladen. Neben der Lokalisierung sind hier noch folgende Anpassungen vorgenommen:

  • Anpassung der function.php, damit die Lokalisierung auch im Backend funktioniert
  • themeweit wurde die Funktion date() gegen date_i18n() ersetzt und
  • the_time('F jS, Y'); gegen die etwas flexiblere Codierung the_time(get_option('date_format'));

das war es!

DAS SAGT DIE WELT

COMPANY CUSTOMER PACT

ein Herz für unsere KundenWir glauben an gute Kundenbeziehungen und offene Kommunikation miteinander.