PHP-Anwendungen mit gettext leicht übersetzbar machen

Übersetzers Liebling
Kommentare

Übersetzungssysteme Marke „Eigenbau“ bringen oftmals Probleme mit sich und machen den Übersetzern bei Änderungen am Text das Leben schwer. gettext verspricht Abhilfe indem es den Übersetzern einheitliche Hilfsmittel zur Verfügung stellt und sie so bequemer arbeiten lässt.

Wer schon einmal eine mehrsprachige Webanwendung entwickelt hat, kennt das Dilemma: Wie sorgt man für eine auch langfristig einfach zu wartende Übersetzungsschnittstelle? Mögliche „Quick’n’dirty“-Lösungen bringen zwar schnelle Erfolge, erschweren Übersetzern aber unnötigerweise ihre Arbeit.

Unsaubere Eigenentwicklungen

Eine einfache Möglichkeit zur Übersetzung zeigt Listing 1. Übersetzungen werden hier in einem assoziativen Array gespeichert, das den Ursprungstext als Schlüssel und die Übersetzung als Wert enthält. Die Funktion translate() prüft, ob die übergebene Zeichenkette im Array mit den Übersetzungen vorhanden ist (isset($translation[$string]) ) sowie ob dafür eine Übersetzung existiert (!empty($translation[$string]) ) und gibt, falls vorhanden, die Übersetzung, ansonsten den String in der ursprünglichen Sprache zurück. Listing 2 stellt eine einfache Übersetzung dar.

Aufmerksame Leser entdecken vielleicht den Fehler im Ausgangstext. Im zweiten Original-String muss anstatt dem Deutschen „Hier“ natürlich das englische Wort „Here“ stehen. Merkt der Programmierer seinen Fehler später und passt seinen Text an, so wird die Übersetzung ungültig. Die translate()-Funktion prüft auf einen Schlüssel, der mit „Here you .“ beginnt, findet jedoch nichts, da in der Übersetzung noch der Schlüssel „Hier you .“ verwendet wird. Es wird keine Übersetzung angezeigt, obwohl auf den ersten Blick eine korrekte Übersetzung existiert. Der Übersetzer wundert sich, dass seine Übersetzung nicht angezeigt wird, obwohl er den String doch scheinbar übersetzt hat. Der Autor dieser Zeilen weiß aus eigener Erfahrung, wie frustrierend und zeitaufwändig diese Art von Fehlern sein kann.

Ähnlich sieht es aus, wenn der Programmierer einen neuen String hinzufügt. Der Übersetzer merkt das nur, wenn er die Anwendung regelmäßig verwendet und ihm bei einer kompletten Durchsicht unübersetzte Strings in der Originalsprache auffallen. Hier wäre eine Möglichkeit wünschenswert, die geänderte oder neue Strings auf einfache Weise ersichtlich macht.

Listing 1: index_eigenbau.php

<?php // Eine einfache Möglichkeit zur Übersetzung.
// Die Übersetzungen werden in dem globalen Array
// $translation gespeichert, das über require
// eingebunden werden muss.
function translate($string) {
	global $translation;

	if (isset($translation[$string]) && !empty($translation[$string])) {
		return $translation[$string];
	} else {
		return $string;
	}
}

// setzt die Sprache auf Deutsch
require_once './german.php';

// Übersetzung ausgeben
echo translate('Welcome to my homepage!');
echo '
'; echo translate('Hier you can find stuff about me.'); ?>
Listing 2: german.php

Doch es gibt Besseres

In genau diese Bresche springt nun gettext [1]. Als freie Software durch das GNU-Projekt [2] entwickelt, erfreut es sich unter Linux und Unix-artigen Betriebssystemen einer großen Verbreitung. Mittlerweile wird es auch immer häufiger von PHP-Anwendungen eingesetzt, schließlich bietet PHP die Möglichkeit, gettext zu unterstützen [3]. Es bietet den Übersetzern Werkzeuge zur einfachen Verwaltung ihrer Übersetzungen und zeigt an, wenn sich Strings ändern oder neue hinzukommen. Dies macht ihnen die Arbeit einfacher und bringt Ihnen hoffentlich mehr und qualitativ hochwertigere Übersetzungen.

gettext bietet eine handvoll Funktionen, wobei die grundlegende Verwendung der wichtigsten schnell erklärt ist:

  • bindtextdomain(string domain, string directory) erstellt eine so genannte Text-Domäne und definiert, in welchem Ordner zu ihr gehörende Übersetzungen liegen.
  • bind_textdomain_codeset(string domain, string encoding) legt die Zeichenkodierung für die genannte Text-Domäne fest.
  • textdomain(string domain) weist das Übersetzungssystem an, Übersetzungen aus der genannten Domäne zu verwenden.
  • gettext(string message) sucht in der aktuellen Domäne nach dem übergebenen Text und liefert, falls vorhanden, seine Übersetzung.
  • _(string message) ist die Kurzform für gettext(). Weniger Schreibarbeit, aber ansonsten äquivalente Verwendung und Funktionalität.
  • ngettext(string msgid_1, string msgid_2, int n) gibt die korrekte Übersetzung für n Objekte aus und beachtet verschiedene Pluralformen.

Text-Domänen kann man sich als die gettext-Variante des simplen Arrays $translation vorstellen. Üblicherweise verwendet man lediglich eine Domäne, es ist aber in manchen Fällen durchaus sinnvoll, verschiedene Domänen zu verwenden und so Strings voneinander abzugrenzen. Dazu später mehr.

Listings 3 und 4 zeigen, wie man das bereits dargestellte Beispiel mit gettext umsetzt. Die .po-Datei enthält Informationen zur Übersetzung (Zeilen 1 bis 16) und anschließend die Übersetzungen. Wie man sieht, befindet sich der Original-String hinter „msgid“ (kurz für Message ID, also Nachrichten-ID), die Übersetzung hinter „msgstr“ (kurz für Message String). Sie lässt sich mit einem beliebigen Texteditor bearbeiten, richtig bequem wird es aber erst mit speziellen Werkzeugen dafür, auf die im folgenden Teil dieser Artikelserie genauer eingegangen wird.

Dort ist von einer .mo-Datei die Rede, Listing 4 zeigt aber eine .po-Datei. Was hat es nun damit auf sich? Um eine hohe Geschwindigkeit zu erreichen, verwendet gettext kompilierte Übersetzungstabellen, sodass keine Zeit auf das Verarbeiten des menschenlesbaren Formats der .po-Datei entfällt. Für uns ist nun erst einmal wichtig, aus der gezeigten .po-Datei eine .mo-Datei zu kompilieren, damit die Übersetzung getestet werden kann.

Listing 3: index_gettext.php

<?php $locale = 'de_DE'; // setzt die Sprache auf Deutsch
$domain = 'myApplication'; // setzt die Domäne
$encoding = 'UTF-8'; // setzt die Zeichenkodierung

// teilt gettext die Sprache mit
setlocale(LC_MESSAGES, $locale);

// teilt gettext mit, wo es die Übersetzungen suchen soll
bindtextdomain($domain, './locale');

// teilt gettext die zu verwendene Zeichenkodierung mit
bind_textdomain_codeset($domain, $encoding);

// weist gettext an, die definierte Domäne zu verwenden
textdomain($domain);

// gettext erwartet die Übersetzung nun in
// ./locale/de_DE/LC_MESSAGES/myApplication.mo

// die Übersetzung ausgeben
echo gettext('Welcome to my homepage!');
echo '
'; // die Übersetzung ausgeben; Kurzform echo _('Hier you can find stuff about me.'); ?>
Listing 4: de_DE.po
  
# German myApplication translation
#
# Hendrik Richter , 2006.
# 
msgid ""
msgstr ""
"Project-Id-Version: my-applicationn"
"Report-Msgid-Bugs-To: n"
"POT-Creation-Date: 2006-10-10 11:55+0200n"
"PO-Revision-Date: 2006-10-10 11:55+0200n"
"Last-Translator: Hendrik Richter n"
"Language-Team: German n"
"MIME-Version: 1.0n"
"Content-Type: text/plain; charset=UTF-8n"
"Content-Transfer-Encoding: 8bitn"

#: ../gettext_index.php:23
msgid "Welcome to my homepage!"
msgstr "Willkommen auf meiner Homepage!"

#: ../gettext_index.php:27
msgid "Hier you can find stuff about me."
msgstr "Hier finden Sie Informationen über mich."
Für Pinguine .

Unter GNU/Linux benötigt man die gettext-Programme. Unter Debian und Derivaten wie Ubuntu installiert man diese mittels aptitude install gettext intltool, unter OpenSuse hilft einem YaST weiter, bei Fedora bedient man sich rpm.

Sind die nötigen Programme installiert, so wechselt man in das Verzeichnis mit der .po-Datei und wandelt diese mit msgfmt de_DE.po -v -o myApplication.mo um. Dies liest die Datei de_DE.po ein und speichert das Ergebnis als myApplication.mo.

Abb. 1: msgfmt erstellt aus der .po-Datei eine .mo-Datei
… und Fenster

Unter Windows ist es am einfachsten, das Programm poEdit [4] zu installieren. Es bringt die benötigen gettext-Programme als ausführbare Windows-Dateien mit, sodass man sich das aufwändige Bauen der benötigen Pakete sparen kann. Anschließend passt man noch die Umgebungsvariable Path an, sodass man die benötigen Programme durch einfache Eingabe ihres Namens starten kann. Unter Windows 2000 und XP öffnet man über einen Rechtsklick auf den ARBEITSPLATZ und dann auf EIGENSCHAFTEN die SYSTEMEIGENSCHAFTEN. Im Reiter ERWEITERT klickt man unten auf den Knopf UMGEBUNGSVARIABLEN und wählt im sich nun öffnendem Fenster unten bei den SYSTEMVARIABLEN PATH aus und fügt nach einem Klick auf BEARBEITEN den Pfad ;C:ProgrammepoEditbin am Ende hinzu.

Nun kann man die Eingabeaufforderung starten (START | PROGRAMME | ZUBEHÖR) und mit cd C:PfadzumphpScriptpo in das Verzeichnis mit den .po-Dateien wechseln, um diese dann zu verarbeiten. Die Benutzung erfolgt analog zur Bedienung unter Unix-artigen Betriebssystemen: msgfmt de_DE.po -v -o myApplication.mo lädt die Datei de_DE.po, kompiliert diese und speichert das Ergebnis in der Datei myApplication.mo.

Abb. 2: Unter Windows sollte man die Umgebungsvariable
Funktioniert nicht?

Wenn die .mo-Datei erstellt und in das entsprechende Verzeichnis (für die Deutsche Übersetzung ist dies ./locale/de_DE/LC_MESSAGES/) kopiert wurden, sollte es theoretisch funktionieren. In der Praxis sieht es meistens anders aus.

Wenn Sie das obige Beispiel aufrufen, werden Sie wahrscheinlich feststellen, dass keine übersetzten Zeichenketten angezeigt werden. Möglicherweise erhalten Sie auch eine Fehlermeldung, dass die gettext-Funktionen nicht existieren.

Um gettext unter PHP nutzen zu können, muss es mit –with-gettext einkompiliert werden. Weiterhin müssen entsprechende Einstellungssätze für Gebietsschemata, so genannte Locales, für die Sprachen, in die übersetzt werden soll, installiert sein. Beides ist bei Standard-Hosting-Paketen unter Linux nicht allzu oft der Fall, unter Windows sieht es noch düsterer aus. Und selbst wenn Sie Linux auf Ihrem Heim-PC installiert haben, ist dies kein Garant dafür, dass es funktioniert. Das Locale für Deutsch heißt oftmals de_DE.UTF-8, sodass PHP bzw. gettext mit der Angabe de_DE aus dem PHP-Skript nichts anfangen können.

Funktioniert doch!

Doch es gibt eine Lösung. Danilo egan hat das Paket php-gettext [5] entwickelt, das die php-Funktionen emuliert, wenn diese nicht vorhanden sind oder aufgrund fehlender Locales nicht funktionieren. Die Software steht unter der GNU General Public Licence und ist frei verwendbar, sofern die Lizenz eingehalten wird. Es erfreut sich einer wachsenden Beliebtheit und wird schon in einigen beliebten PHP-Anwendungen verwendet, beispielsweise in der Blog-Software WordPress [6], der Galerie-Software Gallery [7] oder dem Web-Mailer SquirrelMail [8].

php-gettext bietet alle weiter vorne vorgestellten Funktionen und implementiert diese, falls sie nicht vorhanden sind. Nach dem Einbinden von php-gettext verhält sich PHP beinahe so, als wäre es mit Unterstützung für gettext kompiliert. Dies löst freilich nichts an dem Problem der womöglich fehlenden Locales, die für jede zu verwendende Sprache bereitstehen und installiert sein müssen, doch auch dafür bietet php-gettext eine Lösung.

Es implementiert nämlich einen Modus, der PHPs gettext-Funktionalität lediglich benutzt, wenn PHP mit Unterstützung für gettext kompiliert wurde und das angefragte Locale verfügbar ist. Sollte eine der beiden Voraussetzungen nicht erfüllt sein, so emuliert php-gettext die nötigen Funktionen. Dies hat den entscheidenden Vorteil, dass es immer funktioniert, und auf optimal ausgestatteten System (mit gettext und den nötigen Locales) das Optimum an Leistung rausholt, da es in diesem Fall die nativen gettext-Zugriffe verwendet.

Um diese Funktionen zu benutzen, muss man php-gettext in seine Anwendung einbinden. Der Ordnung halber erstellt man dafür ein Unterverzeichnis gettext, in dem sich die Dateien gettext.inc, gettext.php und streams.php des php-gettext-Pakets befinden. php-gettext kann man dann mittels require_once ‚./gettext/gettext.inc‘; einbinden. Fortan kann man sich sicher sein, dass man auf die bereits erwähnten gettext-Funktionen wie _(string message) zugreifen kann.

Um bei Bedarf auch die Verwaltung der Locales zu emulieren, verwendet man die gewohnten Funktionen, jedoch mit dem Präfix T bzw. T_. Aus bindtextdomain() wird somit T_bindtextdomain(), aus _() wird T_() etc.

Listing 5 zeigt anhand eines Beispiels die Verwendung von php-gettext im so genannten Fallback-Modus. Man sieht, dass es sich von Listing 3 lediglich in der Einbindung von php-gettext sowie dem Voranstellen von T bzw. T_ an alle gettext-Funktionen unterscheidet.

Wenn Sie das Skript aus Listing 5 starten, so sollten Sie den übersetzten Test sehen. Egal, ob Sie GNU/Linux oder Windows verwenden und egal, ob die nötigen Locales installiert sind.

Listing 5: index_php-gettext.php

<?php $locale = 'de_DE'; // setzt die Sprache auf Deutsch
$domain = 'myApplication'; // setzt die Domäne
$encoding = 'UTF-8'; // setzt die Zeichenkodierung

// lädt php-gettext
require_once('./gettext/gettext.inc');

// teilt php-gettext die Sprache mit
T_setlocale(LC_MESSAGES, $locale);

// teilt php-gettext mit, wo es die Übersetzungen suchen soll
T_bindtextdomain($domain, './locale');

// teilt php-gettext die zu verwendene Zeichenkodierung mit
T_bind_textdomain_codeset($domain, $encoding);

// weist php-gettext an, die definierte Domäne zu verwenden
T_textdomain($domain);

// php-gettext erwartet die Übersetzung nun in
// ./locale/de_DE/LC_MESSAGES/myApplication.mo

if (locale_emulation()) {
	// echo 'php-gettext wird verwendet.
'; } else { // echo 'gettext wird nativ verwendet. '; } // die Übersetzung ausgeben echo T_gettext('Welcome to my homepage!'); echo ' '; // die Übersetzung ausgeben; Kurzform echo T_('Hier you can find stuff about me.'); ?>
Text-Domänen

Nun verfügen Sie bereits über die Grundlagen der Arbeit mit gettext, doch neben den zuvor genannten Funktionen gibt es noch einige weitere. Auch diese werden bei Bedarf von php-gettext emuliert, sodass Sie die folgenden Beschreibungen analog zu oben verwenden können, in denen Sie den Funktionen ein T_ voran stellen.

Stellen Sie sich beispielsweise einen Währungsumrechner vor. Dort gibt es einige Zeichenketten, die übersetzt werden können: Zum einen die gesamte Benutzeroberfläche, also Schaltflächen wie UMRECHNEN und erklärende Texte. Zusätzlich gibt es noch eine lange Liste aller verfügbaren Währungen, die man ebenfalls übersetzen möchte. Hier bietet es sich an, zwei Domänen zu verwenden, eine für die Oberfläche des Programms und eine für die Währungen. Erstellt man später ein weiteres Projekt, das die Währungen benötigt, beispielsweise einen Online-Shop, so kann man die vorhandenen Übersetzungen aus der Domäne mit den Währungen problemlos und ohne Anpassungen übernehmen.

Es ist möglich, die mit textdomain() festgelegte Text-Domäne zu umgehen und eine Übersetzung aus einer bestimmten anderen Domäne zu verwenden. Dies erledigen die folgenden Funktionen:

  • dgettext(string domain, string message) sucht in der Domäne domain nach dem übergebenen Text und liefert falls vorhanden seine Übersetzung.
  • dngettext(string domain, string msgid_1, string msgid_2, int n) gibt die korrekte Übersetzung aus der Domäne domain für n Objekte aus und beachtet verschiedene Pluralformen.

Hat man die Text-Domäne mittels textdomain(‚myApplication‘) festgelegt, so erreicht man eine übersetzte Bedieneroberfläche mittels gettext(

psenv::pushli(); eval($_oclass[„text“]); psenv::popli(); ?>

) , übersetzte Währungen mittels dgettext(‚currency‘,

psenv::pushli(); eval($_oclass[„text“]); psenv::popli(); ?>

) .

Locale-Kategorien

Das gettext-System muss natürlich darüber informiert werden, für welche Sprache es die Übersetzungen liefern soll. Dies wird über die Funktion setlocale(int category, string locale) erledigt. In den bisherigen Beispielen wurde die Kategorie LC_MESSAGES auf de_DE gesetzt, doch was hat es damit genau auf sich? Es gibt sechs unterschiedliche Kategorien sowie eine siebte, die alle anderen beinhaltet. Auf diese Weise ist es möglich, bei der Internationalisierung einer Anwendung mehrere unterschiedliche Sprachen zu verwenden. So kann man beispielsweise englischsprachige Texte ausgeben lassen, ein Datum hingegen in deutscher Schreibweise. Die folgenden Werte sind für Kategorien möglich, die der Übersicht wegen durch sieben mit LC_ beginnende Konstanten dargestellt werden:

  • LC_CTYPE (0)für die Klassifizierung und Umwandlung von Zeichen (z.B. strtouper(‚a‘) == ‚A‘).
  • LC_NUMERIC (1) für dezimale Zahlenformatierungen (bspw. 3,14 oder 3.14).
  • LC_TIME (2) für Datums- und Zeitformatierungen (bspw. ’05. November‘ oder ’11/05′).
  • LC_COLLATE (3) für Vergleiche von Zeichenketten (z.B. ‚Apfel‘ , da A vor B kommt).
  • LC_MONETARY (4) für monetäre Zahlenformatierungen (bpsw. 1’999,95 € oder 1,999.95 €).
  • LC_MESSAGES (5) für Textausgaben (bspw. ‚Hallo‘ oder ‚Hello‘).
  • LC_ALL (6) für alle oben genannten Werte.

Für die Bezeichnung der Locales hat man sich auf die Verwendung der ISO-Normen ISO 639 [9] und ISO 3166 [10] geeinigt, die über einen Unterstrich verknüpft werden. ISO 639 bezeichnet die sprachliche Einteilung (beispielsweise de für Deutsch, fr für Französisch), ISO 3166 die geographische (beispielsweise DE für Deutschland, AT für Österreich). de_DE steht also für Deutsch/Deutschland, de_AT hingegen für Deutsch/Österreich.

Kommen wir zurück zum genannten Beispiel eines Währungsrechners. Es ist womöglich gewünscht, dass dieser eine deutsche Bedienoberfläche hat, die Geldbeträge und deren Währungen aber in US-amerikanischer Notation wiedergibt. Setzt man LC_MESSAGES auf de_DE und LC_MONETARY hingegen auf en_US, so hat dies noch nicht den gewünschten Effekt, da die Währungen noch immer auf Deutsch ausgegeben werden. Dies liegt daran, dass gettext standardmäßig die Kategorie LC_MESSAGES benutzt.

Wünschenswert wäre daher eine Möglichkeit, die Kategorie der Locales festzulegen, welche die zu verwendende Sprache bestimmt. Auch hierfür bietet gettext Funktionen, die auch in php-gettext verfügbar sind:

  • dcgettext(string domain, string message, int category) sucht in der Domäne domain nach dem übergebenen Text und liefert, falls vorhanden, seine Übersetzung in die in CATEGORY festgelegte Sprache.
  • dcngettext (string domain, string msg_id_1, string msg_id_2, int n, int category) gibt die korrekte Übersetzung aus der Domäne domain für n Objekte aus, beachtet verschiedene Pluralformen und verwendet die in CATEGORY festgelegte Sprache.

Grob umrissen erreicht man das gewünschte Ergebnis nun mit dem Code aus Listing 6. Es werden zwei Text-Domänen definiert sowie für Textausgaben und Währungsausgaben zwei verschiedene Locales ausgewählt. Bei der Ausgabe des Ergebnisses wird die Übersetzung der Währung aus der Text-Domäne myApplicationCurrency ausgewählt sowie das US-amerikanische Locale verwendet. Für die restlichen Ausgaben wird die Vorgabe verwendet, in diesem Fall de_DE aus der Domäne myApplication.

Bitte beachten Sie, dass der Code aus Listing 6 mit der derzeit aktuellen Version 1.0.7 von php-gettext noch nicht funktioniert. Der Autor dieser Zeilen hat jedoch einen Patch an das Projekt gesendet, der dieses Problem behebt und hoffentlich in die nächste Version einfließt. Auf der diesem Heft beiliegenden CD finden Sie im Unterordner gettext eine inoffizielle Version, die diesen Patch enthält.

Listing 6: currency.php

<?php $domain = 'myApplication'; // setzt die Domäne
$domain_currency = 'myApplicationCurrency';

$encoding = 'UTF-8'; // setzt die Zeichenkodierung

// teilt gettext die Sprachen mit
setlocale(LC_MESSAGES, 'de_DE');
setlocale(LC_MONETARY, 'en_US');

// teilt gettext mit, wo es die Übersetzungen suchen soll
bindtextdomain($domain, './locale');
bindtextdomain($domain_currency, './locale');

// teilt gettext die zu verwendene Zeichenkodierung mit
bind_textdomain_codeset($domain, $encoding);
bind_textdomain_codeset($domain_currency, $encoding);

// weist gettext an, die definierte Domäne zu verwenden
textdomain($domain);

// gettext erwartet die Übersetzung nun in
// ./locale/de_DE/LC_MESSAGES/myApplication.mo
// und
// ./locale/en_US/LC_MESSAGES/myApplicationCurrency.mo

// die Übersetzung ausgeben
// die Ausgabe erfolgt in Deutsch, da gettext standardmäßig
// die Kategorie LC_MESSAGS verwendet, die hier auf de_DE
// gesetzt ist
echo gettext('The result is:');
echo '
'; // hier wird das Ergebnis berechnet // [...] // $result enthält das Ergebnis // $currency enthält die Währung echo $result; // die Ausgabe erfolgt in Englisch, da als Kategorie // LC_MONETARY gewählt ist, die hier auf en_US gesetzt // ist echo dcgettext($domain_currency, $currency, LC_MONETARY); ?>
Da war doch noch …

Sie haben nun das nötige Werkzeug zur Hand, Ihre Anwendungen übersetzbar zu machen. Gehen Sie alle Skript-Dateien durch und markieren Sie die zu übersetzenden Zeichenketten. Doch etwas Wichtiges fehlt noch: die Erstellung der .po-Dateien. Diese müssen nicht mühsam von Hand erstellt werden, denn es gibt Werkzeuge, die als zu übersetzend markierte Strings in Dateien aufspürt und die .po-Datei erstellt.

Dieses Werkzeug heißt xgettext und wird mit xgettext -kT_ngettext:1,2 -kT_ -kT_gettext -L PHP -o myApplication.pot *.php aufgerufen. Der Aufruf untergliedert sich in die folgenden Teile: xgettext ist der Name des Programms; -kT_ngettest:1,2 -kT_ -kT_gettext weist es an, neben den vorgegebenen gettext-Funktionen (wie gettext() und _()) auch auf die php-gettext eigenen Funktionen zu achten, die bekanntlich mit T_ beginnen. -L PHP setzt die Programmiersprache auf PHP, -o myApplication.pot speichert das Ergebnis in der Datei myApplication.pot.

Diese kann nun von den Übersetzern als Vorlage verwendet werden. Dazu wird für jede Sprache eine Kopie erstellt, deren Namen mit der zuvor beschriebenen Benennung der Locales übereinstimmt und mit der Dateierweiterung .po versehen. Diese kann dann von den Übersetzern bearbeitet werden.

Ausblick

Im nächsten Teil erfahren Sie die Tricks und Kniffe, wie Sie das letzte aus gettext herausholen können und den Übersetzern die Arbeit weiter erleichtern können. Sie werden lernen, welche Zeichenketten als zu übersetzend markiert werden sollten und welche nicht, und wie man oft auftretende Fallstricke umgeht.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -