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.
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.
Ü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:
Rufen Sie Yii::t() an den entsprechenden Stellen auf
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.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 demmessage
-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 desmessage
-Komandes führen Sie bitteyiic 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.
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)
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.