Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Geleitwort
Vorwort
1 PEAR – Einführung
2 Authentication
3 Caching
4 Date and Time
5 File Formats
6 HTTP
7 Internationalization
8 Mail
9 Networking
10 PHP
11 Text
12 Web Services
13 Benchmarking
14 Configuration
15 Database
16 File System
17 HTML
18 Images
19 Logging
20 Math
21 Numbers
22 Tools and Utilities
23 XML
24 Selbst Pakete erstellen
25 PECL
Index
Ihre Meinung?

Spacer
 <<   zurück
PHP PEAR von Carsten Möhrke
Anwendung und Entwicklung – Erweiterungen für PHP schreiben
Buch: PHP PEAR

PHP PEAR
798 S., 39,90 Euro
Rheinwerk Computing
ISBN 3-89842-580-0
gp 7 Internationalization
  gp 7.1 I18Nv2
  gp 7.2 Translation2


Rheinwerk Computing

7.2 Translation2  toptop


Besprochene Version: 2.0.0beta6 Lizenz: PHP-Lizenz
Klassendatei(en): Translation2.php; Translation2/Admin.php

Translation2 ist ein Paket, mit dem Sie einfach und schnell mehrsprachige Websites erstellen können. Um die verschiedenen Sprachen zu verwalten, können Sie datenbankbasiert (PEAR::DB, PEAR::MDB und PEAR::MDB2 werden unterstützt) arbeiten, aber auch gettext- oder XML-Dateien nutzen.

Das Paket besitzt eine Factory-Klasse, die als ersten Parameter den Namen des Speichertreibers übergeben bekommt. Danach folgt ein Array mit den notwendigen Optionen für den verwendeten Speichertreiber. Als dritten Parameter können Sie noch ein Array mit Optionen für die Klasse selbst angeben.

Für den ersten Parameter können Sie also einen der Strings 'db', 'mdb','mdb2','gettext' oder 'xml' nutzen. Das darauf folgende Array ist, wie schon erwähnt, vom verwendeten Speichertreiber abhängig. Da mir die Nutzung von gettext- bzw. XML-Dateien in diesem Zusammenhang unwahrscheinlich bzw. nur bedingt sinnvoll erscheint, werde ich nur auf den Datenbankzugriff eingehen. Sollten Sie gettext oder XML nutzen wollen, finden Sie hilfreiche Beispiele in dem Archiv, in dem das Paket vorhanden ist.

Nutzen Sie einen der Datenbank-Layer, so ist das Array folgendermaßen aufzubauen:

$db_opts = array( 
   'hostspec' => 'localhost', // Name oder IP des DB-Servers 
   'database' => 'db',        // Name der Datenbank 
   'phptype'  => 'mysql',     // Typ des Protokolls 
   'username' => 'User',      // Benutzername 
   'password' => 'geheim'     // Passwort 
);

In der Datenbank sind zwei Tabellen vorzusehen. In der einen wird verwaltet, welche Sprachen verfügbar sind, und in der anderen sind die Übersetzungen zu finden.

Die Tabelle zur Verwaltung der installierten Sprachen könnte mit diesen Befehlen angelegt werden:

CREATE TABLE langs ( 
  id varchar(10) NOT NULL, 
  name varchar(200), 
  meta text, 
  error_text varchar(250), 
  encoding varchar(16) NOT NULL DEFAULT 'iso-8859–1' 
); 
CREATE UNIQUE INDEX langs_id_index ON langs (id); 
INSERT INTO langs ( 
           id, name, meta, error_text, encoding) 
           VALUES( 
           "en", "english", "my meta info", 
           "no English translation available", "iso-8859–1");
INSERT INTO langs ( 
           id, name, meta, error_text, encoding) 
           VALUES( 
           "de", "deutsch", "charset: iso-8859–1", 
           "kein deutscher Text verfügbar", "iso-8859–1");

Listing 7.8 SQL-Befehl zum Anlegen der Verwaltungstabelle

Im Feld id werden eindeutige Bezeichner für die Sprache abgelegt, unter denen Sie die Inhalte zu einer Sprache später wieder ansprechen können. Es empfiehlt sich, hier auf ISO-Codes zurückzugreifen, um gewährleisten zu können, dass die Bezeichner immer konsistent genutzt werden können.

Die Spalte name enthält jeweils den eigentlichen Namen der Sprache. Im Feld meta können Sie eine Beschreibung ablegen. Hierbei handelt es sich um eine reine Meta-Information, die für das Paket selbst nicht weiter von Belang ist.

Wichtig hingegen ist das Feld error_text, in dem Sie einen Text festlegen können und sollten, der ausgegeben werden kann, wenn für einen Text keine Übersetzung vorhanden ist. Da es immer mal vorkommt, dass eine Übersetzung nicht ganz komplett ist, ist das eine sehr hilfreiche Funktionalität. Bitte beachten Sie, dass Sie einen Decorator benutzen müssen, damit der Text ausgegeben wird. Weitere Informationen zu den Decorators finden Sie auf Seite 227.

In der letzten Spalte, die den Namen encoding hat, definieren Sie den Zeichensatz, der für diese Sprache genutzt wird.

Die beiden INSERT-Befehle fügen die Initialisierung für die Sprachen Deutsch und Englisch ein. Diese stehen in enger Beziehung mit der Tabelle i18n, die zum Verwalten der eigentlichen Textbausteine dient und so angelegt werden kann:

CREATE TABLE i18n ( 
  id TEXT NOT NULL, 
  page_id varchar(100), 
  en TEXT, 
  de TEXT 
); 
CREATE UNIQUE INDEX i18n_id_index ON i18n (id(16), page_id);

Listing 7.9 Anlegen der Tabelle für die Textbausteine

Die Tabelle zum Verwalten der Texte ist so aufgebaut, dass für jede der installierten Sprachen eine eigene Spalte vorgesehen ist. Um eine Übersetzung für einen bestimmten Text zu finden, wird dieser über eine Kombination aus id und page_id angesprochen. In der Spalte id ist »Name« für den Text-Block enthalten, der auf einer Seite eindeutig sein muss. page_id enthält jeweils einen eindeutigen Bezeichner für jede Seite. Die Kombination aus id und page_id ist somit eindeutig.

Bevor Sie eine mehrsprachige Website erstellen können, stellt sich natürlich die Frage, wie die Texte in den entsprechenden Speichercontainer kommen. Dazu ist eine Verwaltungsklasse namens Translation2_Admin vorgesehen, auf die ich zuerst eingehen möchte.

Möchten Sie in Erfahrung bringen, welche Sprachen installiert sind, ist die Methode get() hilfreich. Bekommt sie keinen Parameter übergeben, liefert sie ein Array zurück, das Informationen zu den verfügbaren Sprachen enthält. Der Schlüssel wird jeweils durch die id dargestellt, und der Wert ist der Name der Sprache.

require_once('Translation2/Admin.php'); 
$db_opts = array( 
            'hostspec' => 'localhost', 
            'database' => 'trans', 
            'phptype'  => 'mysql', 
            'username' => 'user', 
            'password' => 'geheim' 
            ); 
 
$tr_admin = Translation2_Admin::factory('db',$db_opts); 
$langs=$tr_admin->getLangs(); 
if (true === PEAR::isError($langs)) 
{ 
   die ($langs->getMessage()); 
} 
 
echo "Verf&uuml;gbare Sprachen:<br />"; 
foreach ($langs as $id => $name) 
{ 
   echo "Sprache: $name  ID: $id<br />"; 
}

Listing 7.10 Auslesen der installierten Sprachen

Um Texte für die einzelnen Sprachen einzufügen, ist add() vorgesehen. Diese Methode bekommt als ersten Parameter die ID des Strings übergeben, über den er eindeutig auf einer Seite identifiziert werden kann. Der zweite Parameter ist die ID der Seite. Möchten Sie nicht mit einer Seiten-ID arbeiten, können Sie hier einfach null übergeben. Als letzter Parameter folgt schließlich ein Array mit den Übersetzungen, die eingefügt werden sollen. Die ID der Sprache dient dabei als Schlüssel für das Array-Element.

$translations = array ( 
                  'de' => '&Uuml;bersetzung', 
                  'en' => 'Translation' 
                ); 
$tr_admin->add ('uebersetzung','home',$translations);

Existiert schon eine bestimmte Übersetzung, so können Sie diese auch aktualisieren bzw. verändern, wenn Sie die Methode update() aufrufen, bei der die Parameter-Liste identisch mit der von add() ist.

Schön ist, dass Sie auch ohne Probleme eine komplette Sprache ergänzen können. Die erforderlichen Tabellenspalten bzw. Dateieinträge werden dabei automatisch angelegt. addLang(), die Methode, die die Sprache hinzufügt, bekommt ein Array mit den erforderlichen Informationen übergeben.

Das Element lang_id enthält die ID der Sprache, die ergänzt werden soll. name verweist auf den Namen der Sprache, meta enthält die Meta-Informationen und error_text den Text, der ausgegeben werden soll, wenn eine Übersetzung nicht verfügbar ist. Auch hier können Sie die bereits enthaltenen Daten aktualisieren, wozu die Methode updateLang() definiert ist. Sie bekommt ein Array übergeben, dessen Aufbau identisch mit dem bei addLang() ist. Die Sprache, die aktualisiert werden soll, wird über das Element lang_id identifiziert. Somit kann diese Information auch nicht geändert werden.

Möchten Sie die ID ändern, können Sie die Sprache nur löschen und wieder neu hinzufügen. Zum Löschen einer kompletten Sprache ist removeLang() definiert. Die Methode benötigt nur die ID der Sprache als Parameter. Standardmäßig wird die Sprache dann nur aus der Tabelle langs bzw. aus der entsprechenden Datei entfernt. Die eigentlichen Texte bleiben erhalten, solange Sie der Methode removeLang() als zweiten Parameter nicht den Wert true übergeben.

Allerdings können Sie auch die Texte für eine einzelne Übersetzung in allen Sprachen entfernen. Die Methode remove(), die das für Sie erledigt, benötigt die ID des Strings als Parameter. Sollten Sie eine Seiten-ID genutzt haben, müsste diese als zweiter Parameter übergeben werden.

Die Administrationsklasse kann aber noch mehr. Und zwar können Sie auch alle Methoden nutzen, die nachfolgend beschrieben sind. Diese Methoden gehören zur Klasse Translation2, die zur eigentlichen Ausgabe der Daten gedacht ist und gleichzeitig die Superklasse von Translation2_Admin ist.

Die Methode factory(), die Ihnen ein Objekt zur Verfügung stellt, ist auch hier wieder definiert und verhält sich genau wie die bei Translation2_Admin.

Auch hier können Sie die installierten Sprachen wieder mit getLangs() auslesen und erhalten ein Array mit den IDs und den Namen der Sprachen. Um alle Informationen zu einer Sprache zu erhalten, können Sie der Methode getLang() die ID einer Sprache übergeben. Sie erhalten dann ein Array mit den Feldern name, meta, error_text.

Um einen String in einer bestimmten Sprache auszulesen, ist die Methode get() vorgesehen, die die ID des Textes, die der Seite und die der Sprache übergeben bekommt. Sie liefert den entsprechend lokalisierten String zurück. Ist der Text nicht vorhanden, wird die Standard-Fehlermeldung für die Sprache zurückgegeben, wenn der entsprechende Decorator genutzt wird. Um im Fehlerfall einen anderen Text auszugeben, können Sie der Methode auch noch eine Fehlermeldung als vierten Parameter übergeben, der dann im Falle eines Fehlers zurückgegeben wird, wobei auch in diesem Fall ein Decorator genutzt werden muss, wie Sie Seite 227 entnehmen können.

require_once('Translation2.php'); 
$db_opts = array( 
            'hostspec' => 'localhost', 
            'database' => 'trans', 
            'phptype'  => 'mysql', 
            'username' => 'user', 
            'password' => 'geheim' 
            ); 
 
$tr = Translation2::factory('db',$db_opts); 
 
$text_id='uebersetzung'; 
 
$text = $tr->getRaw($text_id,'home', 'de'); 
if (true === PEAR::isError($text)) 
{ 
   die ($text->getMessage()); 
} 
echo "Deutsch: $text<br />"; 
 
$text = $tr->get($text_id,'home', 'en'); 
if (true === PEAR::isError($text)) 
{ 
   die ($text->getMessage()); 
} 
echo "Englisch: $text<br />"; 
/* Ausgabe: 
** Deutsch: Übersetzung 
** Englisch: Translation 
*/

Listing 7.11 Ausgabe von lokalisierten Texten

Wichtig hierbei ist, dass die korrekten Fehlermeldungen nur dann zurückgegeben werden, wenn die Sprache, die Sie auslesen wollen, auch angelegt ist. Ist diese Sprache nicht angelegt, bekommen Sie ein PEAR_Error-Objekt zurück.

Die Methode get() kennt aber noch ein spannendes Feature. Und zwar können Sie in den übersetzten Texten Platzhalter nutzen, die beim Auslesen mit get() automatisch durch einen Wert ersetzt werden. Ein solcher Platzhalter wird mit && am Anfang und Ende markiert. Sie würden den Text also beispielsweise mit

$translations = array ('de' => 'Hallo &&user&&'); 
$tr_admin->add ('hallo','home',$translations);

hinzufügen. Wenn Sie den Text auslesen, übergeben Sie der Methode setParams() ein Array, das die Namen der Variablen jeweils als Schlüssel hat. Der dazugehörige Wert wird dann an Stelle der Variable automatisch in den zurückgelieferten Text eingefügt.

$tr->setParams(array('user' => 'Paul')); 
$text = $tr->get('hallo','home', 'de'); 
// $text enthaelt Hallo Paul

Möchten Sie diese Funktionalität nicht nutzen, können Sie anstelle von get() auch die Methode getRaw() verwenden, die dieselbe Parameterliste hat. Sie versucht nicht, Variablen zu ersetzen, und ist daher ein wenig schneller.

Sind auf einer Seite sehr viele Aufrufe von get() oder getRaw() zu finden, können die Methoden setLang() und setPageID() Ihnen Zeit sparen. Mit ihnen können Sie die ID einer Sprache bzw. die ID der Seite, die genutzt wird, festlegen, so dass diese nicht bei jedem Aufruf von get() bzw. getRaw() übergeben werden müssen.

$tr->setPageID('home'); 
$tr->setLang('de'); 
 
$text = $tr->get('uebersetzung');

Nachdem Sie die Grundlagen kennen, möchte ich Ihnen noch die Decorators vorstellen. Hierbei handelt es sich um eine Art Filter, der in der Lage ist, die Texte, die ausgegeben werden sollen, automatisch zu verändern. Ein Decorator-Objekt verhält sich genau wie ein Translate2- bzw. ein Translate2_Admin-Objekt. Um ein Decorator-Objekt zu erhalten, rufen Sie die Methode getDecorator() auf und übergeben Ihr den Namen des Decorators.

Sollen die ausgegebenen Texte beispielsweise mit HTML-Entitäten versehen werden, steht der Decorator SpecialChars zur Verfügung:

$tr = Translation2::factory('db',$db_opts); 
$tr = $tr->getDecorator('SpecialChars'); 
$text = $tr->get('uebersetzung','home','de');

Sie können auch zwei Decorator-Klassen miteinander kombinieren, indem Sie mit dem generierten Decorator noch einen zweiten ableiten:

$tr = $tr->getDecorator('ErrorText'); 
$tr = $tr->getDecorator('SpecialChars');

Mit ErrrorText wird dafür gesorgt, dass die Fehlermeldung ausgegeben wird, die in der Tabelle langs definiert ist, wenn in der angefragten Sprache keine Übersetzung gefunden werden kann.

Eine Liste aller Decorators finden Sie in Tabelle 7.3.


Tabelle 7.3 Definierte Decorators
Konstante für getDecorator() Erläuterung
'CacheLiteFunction' Nutzt PEAR::Cache_Lite, um zu verhindern, dass die Übersetzung jedes Mal neu eingelesen werden muss.
'CacheMemory' Einmal eingelesene Daten werden im RAM gecacht.
'DefaultText' Legt fest, dass der vierte Parameter von get() oder getRaw() genutzt wird, wenn keine Übersetzung vorhanden ist.
'ErrorText' Sollte keine Übersetzung in der gewünschten Sprache vorhanden sein, wird der vorgegebene Fehlertext zurückgegeben.
'Lang' Legt eine »Fallback-Sprache« fest.
'Iconv' Konvertiert in einen anderen Zeichensatz.
'SpecialChars' Legt fest, dass Sonderzeichen in Entitäten konvertiert werden.
'UTF8' Konvertiert Texte, die in der Datenbank im UTF-8-Zeichensatz vorliegen, für die Ausgabe nach ISO-8859–1.

Nutzen Sie einen der beiden Decorators Lang oder Iconv, müssen Sie noch die Methode setOption() aufrufen.

Der Decorator Lang definiert, dass in dem Fall, dass eine Übersetzung in einer bestimmten Sprache nicht gefunden werden kann, eine andere Sprache genutzt werden soll. Um welche Sprache es sich dabei handelt, legen Sie mit der Methode setOption() fest, die als ersten Parameter 'fallbackLang' und als zweiten die Sprach-ID übergeben bekommt.

$tr = Translation2::factory('db',$db_opts); 
$tr = $tr->getDecorator('Lang'); 
$tr->setOption('fallbackLang', 'en'); 
$text = $tr->get('uebersetzung','home','de');

Der Decorator Iconv kann den zurückgegebenen Text in einen anderen Zeichensatz konvertieren. Welcher Zeichensatz genutzt werden soll, muss wiederum mit setOption() festgelegt werden. Der erste Parameter ist dabei der String 'encoding' und der zweite der Zeichensatz, der genutzt werden soll.

 <<   zurück
     
  Zum Katalog
Zum Katalog: PHP PEAR
PHP PEAR
Jetzt bestellen!
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: PHP 5.6 und MySQL 5.7






 PHP 5.6 und
 MySQL 5.7


Zum Katalog: Einstieg in PHP 5.6 und MySQL 5.6






 Einstieg in PHP 5.6
 und MySQL 5.6


Zum Katalog: Responsive Webdesign






 Responsive Webdesign


Zum Katalog: Moderne Websites entwickeln






 Moderne Websites
 entwickeln


Zum Katalog: MySQL 5.6






 MySQL 5.6


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo








Copyright © Rheinwerk Verlag GmbH 2007
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de