Internationalisierung

Unter Internationalisierung (engl: internationalization bzw. I18N, wegen 18 Buchstaben zwischen I und N) versteht man den Prozess, eine Softwareanwendung so zu entwerfen, dass sie an verschiedene Sprachen und Regionen angepasst werden kann, ohne Änderungen an der Programmlogik vornehmen zu müssen. Für Webanwendungen ist dieser Punkt von besonderem Interesse, da Besucher aus der ganzen Welt zu erwarten sind.

Yii unterstützt I18N in verschiedenen Belangen:

  • Es enthält Lokaliesierungsdaten für jede mögliche Sprache und Variante.
  • Es enthält Features zum Übersetzen von Textmeldungen und Dateien.
  • Es beherrscht landesspezifische Datums- und Zeitformatierung.
  • Es beherrscht landesspezifische Zahlenformatierung.

In den folgenden Abschnitten gehen wir auf jeden dieser Punkte näher ein.

1. Locale und Sprache

Eine Locale (sinngem.: Gebietsschema) besteht aus einer Reihe von Parametern, die für einen Benutzer die Sprache, das Land und alle speziellen abweichenden Einstellungen enthält, die für seine Anwenderschnittstelle von Bedeutung sind. In der Regel wird sie durch eine ID bestimmt, die sich aus SprachID und LandID zusammensetzt. Die ID en_US steht zum Beispiel für die Locale Englisch und Vereinigte Staaten. Um Konsistenz zu wahren, werden alle Locale-IDs in das Format SprachID oder SprachID_LandID in Kleinbuchstaben gebracht (z.B. en, en_us).

Locale-Daten werden durch eine Instanz vom Typ CLocale verkörpert. Sie enthält locale-abhängige Informationen inklusive Währungssymbole, Zahlensymbole, Währungsformate, Zahlenformate, Datums- und Zeitformate und datumsbezogene Namen. Da die Sprachinformation bereits in der Locale-ID enthalten ist, wird diese nicht von CLocale bereitgestellt. Die Begriffe Locale und Sprache werden daher oft gleichbedeutend verwendet.

Für eine gegebene Locale-ID erhält man die entsprechende Instanz von CLocale über CLocale::getInstance($localeID) oder CApplication::getLocale($localeID).

Info: Yii enthält Locale-Daten für fast alle Sprachen und Länder. Die Daten stammen vom Common Locale Data Repository (CLDR). Jede Locale bietet nur einen Teil der CLDR-Daten, da in den Originaldaten viele kaum verwendete Informationen enthalten sind. Sie können auch Ihre eigenen, angepassten Locale-Daten verwenden. Dazu setzen Sie die Eigenschaft CApplication::localeDataPath auf das Verzeichnis, dass die angepassten Locale-Daten enthält. Zum Anlegen dieser Dateien verweisen wir auf die Dateien unter framework/i18n/data.

Bei einer Yii-Anwendung unterscheidet man zwischen Zielsprache und Quellsprache (engl: source language). Die Zielsprache bezieht sich auf die Sprache (Locale) der Zielgruppe, für die die Anwendung geschrieben wurde, während die Quellsprache die Sprache (Locale) ist, in der die Quelltexte der Anwendung vorliegen. Internationalisierung kommt nur dann zur Anwendung, wenn diese beiden Sprachen sich unterscheiden.

Tip: Es ist sinnvoll Englisch als Quellsprache zu verwenden, da es einfacher ist, Übersetzer zu finden, die von Englisch in eine andere Sprache übersetzen.

Die Zielsprache kann in der Anwendungskonfiguration definiert oder dynamisch angepasst werden, bevor die Internationalisierung durchgeführt wird.

Tipp: Manchmal möchte man evtl. die Zielsprache auf die vom Besucher bevorzugte Sprache (entsprechend seinen Browsereinstellungen) setzen. Man kann dazu die SprachID seiner bevorzugten Sprache über CHttpRequest::preferredLanguage beziehen.

2. Übersetzung

Am häufigsten wird wahrscheinlich das Übersetzungsfeature von I18N benötigt, was die Übersetzung von Textmeldungen und Views beinhaltet. Bei ersterem werden einzelne Textteile in die gewünschte Sprache übersetzt, bei letzterem ganze Dateien.

Eine Übersetzungsanfrage besteht aus dem zu übersetzenden Objekt, der Quellsprache des Objekts und der Zielsprache in die das Objekt übersetzt werden soll. Die Quellsprache wird von Yii standardmäßig auf die Quellsprache der Anwendung gesetzt, die Zielsprache auf die momentane Sprache der Anwendung. Falls Quell- und Zielsprache gleich sind, findet keine Übersetzung statt.

Übersetzen von Textmeldungen

Textmeldungen werden durch Aufruf von Yii::t() übersetzt. Die Methode übersetzt den übergebenen Text von der Quellsprache in die Zielsprache.

Beim Übersetzen einer Meldung muss deren Kategorie angegeben werden, da Texte je nach Kategorie (bzw. Kontext) unterschiedlich übersetzt werden könnten. Die Kategorie yii bleibt dabei Meldungen des Yii-Frameworks vorbehalten.

Textmeldungen können auch Platzhalter für Parameter enthalten, die beim Aufruf von Yii::t() mit den tatsächlichen Parameterwerten ersetzt werden. Bei der folgenden Übersetzungsanfrage, würde der Platzhalter {alias} im Text durch den tatsächlichen Wert für alias ersetzt.

Yii::t('app', 'Pfadalias "{alias}" wurde geändert.',
    array('{alias}'=>$alias))

Hinweis: Zu übersetzende Textmeldungen müssen statische Strings sein. Sie dürfen keine Variablen enthalten, die den Inhalt des Textes verändern würden (z.B. "Ungültiger Inhalt einer {$meldung}.") Benutzen Sie Platzhalter für Parameter, wenn eine Textmeldung je nach Parameter variieren soll.

Übersetzte Texte werden in einem Magazin gespeichert, das wir als Textquelle (engl.: message source) bezeichnen. Eine Textquelle wird von einer Instanz vom Typ CMessageSource oder deren Kindklasse dargestellt. Beim Aufruf von Yii::t() sucht die Routine in der Textquelle nach der Textmeldung und liefert die übersetzte Version zurück, falls gefunden.

Yii stellt die folgenden Arten von Textquellen zur Auswahl. Sie können CMessageSource auch erweitern, um ihren eigenen Typ einer Textquelle zu erstellen.

  • CPhpMessageSource: Die übersetzten Texte werden als Schlüssel-Wert-Paare in einem PHP-Array gespeichert. Die ursprüngliche Meldung wird als Schlüssel verwendet, die Übersetzung als Wert. Jedes Array steht für eine bestimmte Kategorie und wird unter dem Namen dieser Kategorie in jeweils einem PHP-Script gespeichert. Sämtliche PHP-Dateien mit Übersetzungen für eine Sprache werden in einem Verzeichnis mit dem Namen der Locale-ID abgelegt. Alle diese Verzeichnisse liegen wiederum unterhalb eines Basisverzeichnisses, dessen Ort mit basePath bestimmt wird.

  • CGettextMessageSource: Die übersetzten Texte werden als GNU Gettext-Dateien abgelegt.

  • CDbMessageSource: Die übersetzten Texte werden in Datenbanktabellen gespeichert. Für weitere Details ziehen Sie bitte die API-Dokumentation für CDbMessageSource zu rate.

Eine Textquelle wird als Anwendungskomponente geladen. Yii belegt bereits eine Anwendungskomponente namens messages vor, um die Textmeldungen einer Anwendung zu speichern. Standardmäßig ist diese Textquelle eine CPhpMessageSource mit dem Basisverzeichnis protected/messages.

Zusammenfassend sind folgende Schritte nötig, um Textmeldungen übersetzen zu können:

  1. Rufen Sie Yii::t() an den entsprechenden Stellen auf

  2. Erstellen Sie PHP-Dateien mit Übersetzungen gemäß dem Schema protected/messages/LocaleID/KategorieName.php. Jede Datei liefert einfach ein Array mit übersetzten Texten zurück. Beachten Sie, dass wir hier davon ausgehen, dass Sie die vorgegebene CPhpMessageSource zur Speicherung der übersetzten Texte verwenden.

  3. Konfigurieren Sie CApplication::sourceLanguage und CApplication::language.

Tipp: Wenn Sie CPhpMessageSource als Textquelle einsetzen, können Sie den yiic-Befehl zum Verwalten der Übersetzungen verwenden. Mit dem message-Kommando können Sie die zu übersetzenden Meldungen aus ausgewählten Quelldateien extrahieren und bei Bedarf mit bereits vorhandenen Übersetzungen zusammenführen. Für weitere Details zur Verwendung des message-Komandes führen Sie bitte yiic help message aus.

Textmeldungen einer Erweiterung (z.B. eines Widgets oder eines Moduls) können gesondert behandelt werden, sofern CPhpMessageSource zum Verwalten verwendet wird. Falls eine Meldung zu einer Erweiterung Xyz gehört, kann die Kategorie im Format Xyz.kategorieName angegeben werden. Die entsprechende Datei wird dann in BasisPfad/messages/SprachID/kategorieName.php gesucht, wobei BasisPfad dem Verzeichnis entspricht, in dem die Klassendatei der Erweiterung liegt. Wenn man Yii::t() zum Übersetzen von Erweiterungstexten verwendet, sollte man also stattdessen dieses Format verwenden:

Yii::t('Xyz.kategorieName', 'Zu übersetzender Text')

Yii unterstützt das Auswahlformat (engl.: choice format), auch als Pluralformat bekannt. Dieses Format bezieht sich auf die Auswahl einer Übersetzung in Abhängigkeit von einem gegebenen Zahlenwert. Zum Beispiel gibt es für das Wort 'Buch' im Deutschen eine Singular- und eine Pluralform, während sich das Wort in anderen Sprachen gar nicht (Chinesisch) oder nach komplexen Regeln (Russisch) in Abhängikeit von der Anzahl ändern kann. Das Auswahlformat löst dieses Problem auf einfache und dennoch wirksame Weise.

Um das Auswahlformat zu verwenden, muss eine übersetzte Meldung aus einer Folge von Ausdruck-Übersetzungs-Paaren bestehen, die wie folgt durch | getrennt werden:

'ausdr1#text1|ausdr2#text2|ausdr3#text3'

wobei ausdrN sich auf einen gültigen PHP-Ausdruck bezieht, der in einen boole'schen Wert resultiert und anzeigt, ob die zugehörige Übersetzung verwendet werden soll. Der erste Text, dessen Ausdruck ein true liefert, wird verwendet. Ein Ausdruck kann auch eine spezielle Variable n (nicht $n!) verwenden, die den Zahlenwert enthält, der als erster Parameter übergeben wurde. Nehmen wir zum Beispiel an, die übersetzte Meldung sei

'n==1#ein Buch|n>1#viele Bücher'

und beim Aufruf von Yii::t() würde man den Wert 2 im Parameter-Array der Meldung übergeben, so würde letztlich viele Bücher als Übersetzung verwendet:

Yii::t('app', 'n==1#ein Buch|n>1#viele Bücher', array(1)));
// Oder seit Version 1.1.6
Yii::t('app', 'n==1#ein Buch|n>1#viele Bücher', 1));

Der Ausdruck n==Zahl kann in Kurzschreibweise auch als einzelne Zahl angegeben werden:

'1#ein Buch|n>1#viele Bücher'

Format für Pluralformen

Seit Version 1.1.6 kann das CLDR-basierte Auswahlformat für Pluralformen auch mit einer einfacheren Syntax verwendet werden. Das ist bei Sprachen mit komplexen Pluralformen sehr nützlich.

Die obige Regel für deutsche Pluralformen kann damit wie folgt geschrieben werden:

Yii::t('test', 'Gurke|Gurken', 1);
Yii::t('test', 'Gurke|Gurken', 2);
Yii::t('test', 'Gurke|Gurken', 0);

Dieser Code liefert:

Gurke
Gurken
Gurken

Sollen Zahlen mit eingebunden werden, kann man auch dieses Format verwenden:

echo Yii::t('test', '{n} Gurke|{n} Gurken', 1);

{n} ist hier ein Platzhalter für die übergebene Zahl. Im Beispiel wird 1 Gurke ausgegeben.

Man kann auch weitere Parameter übergeben:

Yii::t('test', '{username} hat eine Gurke|{username} hat {n} Gurken',
array(5, '{username}' => 'samdark'));

und numerische Parameter sogar ersetzen lassen:

function convertNumber($zahl)
{
    // ... hier Zahl zu Wort konvertieren ...
    return $zahl;
}
 
Yii::t('test', '{n} Gurke|{n} Gurken',
array(5, '{n}' => convertNumber(5)));

In einigen Sprachen, wie etwa im Russischen gibt es noch komplexere Pluralregeln. So würde zum Beispiel

Yii::t('app', '{n} Gurke|{n} Gurken', 62);
Yii::t('app', '{n} Gurke|{n} Gurken', 1.5);
Yii::t('app', '{n} Gurke|{n} Gurken', 1);
Yii::t('app', '{n} Gurke|{n} Gurken', 7);

mit der Übersetzung

'Gurke|Gurken' => 'огурец|огурца|огурцов|огурца',

zu dieser Ausgabe führen:

62 огурца
1.5 огурца
1 огурец
7 огурцов

Info: Weitere Informationen darüber, wieviele Werte man in welcher Reihenfolge angeben kann finden auf der Seite mit den Pluralregeln einzelner Sprachen des CLDR.

Übersetzen ganzer Dateien

Dateien werden durch Aufruf von CApplication::findLocalizedFile() übersetzt. Bei einem gegebenen Dateipfad für eine zu übersetzende Datei sucht diese Methode im Unterverzeichnis LocaleID nach einer Datei mit dem selben Namen. Falls gefunden, wird der Pfad zu dieser Datei zurückgeliefert, andernfalls der Pfad zur Originaldatei.

Übersetzte Dateien werden hauptsächlich beim Rendern von Views verwendet. Wenn in einem Controller oder einem Widget eine der Render-Methoden aufgerufen wird, werden die View-Dateien automatisch übersetzt. Wenn die Zielsprache z.B. auf zh_cn gesetzt wurde, während die Quellsprache en_us ist, würde beim Rendern des Views edit, nach der View-Datei protected/views/ControllerID/zh_cn/edit.php gesucht werden. Wird diese Datei gefunden, wird diese übersetzte Version zum Rendern verwendet, andernfalls die Datei protected/views/ControllerID/edit.php.

Übersetzte Dateien eignen sich auch für andere Zwecke. Zum Beispiel um übersetzte Bilder zu verwenden oder um locale-abhängige Daten einzubinden.

3. Datums- und Uhrzeitformatierung

Verschiedene Länder und Regionen verwenden oft unterschiedliche Formate für Datum und Uhrzeit. Die Aufgabe bei der Formatierung von Datum und Uhrzeit besteht also darin, einen Datums- oder Uhrzeitstring gemäß der angegebenen Locale zu erzeugen. Yii stellt dazu CDateFormatter (Datumsformatierer) zur Verfügung.

Jede Instanz von CDateFormatter ist mit einer bestimmten Ziel-Locale verknüpft. Um den Formatierer für die Ziel-Locale der gesamten Anwendung zu erhalten, kann man einfach auf die Eigenschaft dateFormatter der Applikation zugreifen.

Die Klasse CDateFormatter bietet hauptsächlich zwei Methoden zum Formatieren eines UNIX-Zeitstempels (engl.: timestamp) an.

  • format: Diese Methode formatiert den gegebenen UNIX-Zeitstempel gemäß einem anpassbaren Muster in einen String (z.B. $dateFormatter->format('dd.MM.yyyy',$timestamp))

  • formatDateTime: Diese Methode formatiert den gegebenen UNIX-Zeitstempel gemäß dem in der Ziel-Locale vordefinierten Muster in einen String. (z.B. short für kurzes Datumsformat, long für langes Zeitformat)

4. Zahlenformatierung

Genau wie Datum und Uhrzeit können auch Zahlen je nach Land und Region unterschiedlich formatiert werden. Zahlenformatierung beinhalted dezimale Formatierung, Währungsformatierung und Prozentsatzformatierung. Zu diesem Zweck stellt Yii die Klasse CNumberFormatter (Zahlenformatierer) zur Verfügung.

Um den Zahlenformatierer für die Ziel-Locale der gesamten Anwendung zu beziehen, kann man auf die Eigenschaft numberFormatter der Applikation zugreifen.

Die folgenden Methoden werden von CNumberFormatter zum Formatieren eines Integer- oder Double-Werts bereitgestellt.

  • format: Diese Methode formatiert die gegebene Zahl gemäß einem anpassbaren Muster in einen String (z.B. $numberFormatter->format('#,##0.00',$number)).

  • formatDecimal: Diese Methode formatiert die gegebene Zahl, indem sie das in der Ziel-Locale vorgegebene Muster für Dezimalzahlen verwendet.

  • formatCurrency: Diese Methode formatiert die gegebene Zahl sowie den Währungscode, indem sie das in der Ziel-Locale vorgegebene Währungsmuster verwendet.

  • formatPercentage: Diese Methode formatiert die gegebene Zahl, indem sie das in der Ziel-Locale vorgegebene Prozentsatz-Muster verwendet.

Be the first person to leave a comment

Please to leave your comment.