Sicherlich hat jeder Beginner mit dem ZendFramework einen Haufen Fragen wie man das eine oder andere richtig einsetzt und die Doku des ZendFrameworks wirft in einigen Kapiteln mehr Fragen als Lösungen auf. Hilfreich ist in jedem Fall immer auch das ZFForum in dem sehr viele Fragen gelöst werden. Allerdings wird man sich bei speziellen Dingen dort größtenteils einen Wolf suchen, wie zum Beispiel eine simple Beschreibung wie man mit Zend_Translate und Gettext eine lauffähige Version bekommt. In diesem Artikel führe ich ein einfaches Beispiel auf wie man Zend_Translate mit Gettext Übersetzungsdateien korrekt benutzt.
Das tückische bei Zend_Translate ist, dass keine Exception oder Warnung angezeigt wird, wenn Zend_Translate die Übersetzungsdateien nicht finden kann. Somit wundert man sich laufend dass das nicht funktioniert und übersetzte Strings nicht übersetzt werden. Dieses simple Beispiel funktioniert für mich einwandfrei wobei ich allerdings nicht mit einer Bootstrap-Datei sondern mit einer eigenen Bootstrap-Klasse arbeite (das nur mal am Rande erwähnt, allerdings macht es keinen Unterschied).
Im Bootstrapper initialisiere ich vorher für schnellere Übersetzung bei der Ausgabe ebenfalls Zend_Cache, welches grundsätzlich in jedem Projekt Anwendung finden sollte.
Die Verzeichnisstruktur:
/var/www/domain.de = Basis-Root Verzeichnis /application /application/configurations /application/controller /application/languages /application/languages/de_DE.mo /application/languages/de_DE.po /application/layouts /application/layouts/layout.phtml /application/models /application/plugins /application/views /application/views/scripts /application/views/scripts/index /application/views/scripts/index/index.phtml /application/bootstrap.php /htdocs /htdocs/index.php /htdocs/css/ /htdocs/css/styles.css /tmp
Wie man sieht benutzte ich die von Zend vorgeschlagene Verzeichnisstruktur (wieso sollte ich das auch verändern) und benutze zusätzlich Zend_Layout für die View-Schicht. In diesem Beispiel verwende ich auch all diese Elemente. Im include_path des virtuellen Hosts sind das Zend_Framework wie auch der vHost selbst natürlich enthalten, so dass auch alle Dateien gefunden werden können.
Die Gettext – Übersetzungsdateien /application/languages/de_DE.po bearbeite ich mit POEdit und sieht folgendermaßen aus:
msgid "Zend_Translate example" msgstr "Zend_Translate Beispiel" msgid "This is an example of Zend_Translate" msgstr "Dies ist ein Beispiel von Zend_Translate"
Sobald diese de_DE.po mit POEdit gespeichert wird, wird eine binäre Übersetzungsdatei erzeugt. Nun findet man folgendes im Verzeichnis: /application/languages/de_DE.mo
In der /htdocs/index.php definiere ich lediglich den Aufruf zur bootstrap.php:
require_once('../application/bootstrap.php');
Übrigens, bewußt schließe ich nicht PHP mit ?> um Fehlermeldung wegen Leerzeichen oder Leerzeilen hinter dem Abschluss bei HEADER-Ausgaben zu verhindern.
Meine /application/bootstrap.php sieht folgendermaßen aus:
// /application - Pfad als Konstante definieren define("APP_PATH",dirname(__FILE__)); // Für den /tmp brauchen wir noch den Root-Pfad $root = preg_match("/application/i","",dirname(__FILE__)); // Models und Plugins Verzeichnis im Include-Path hinzufügen set_include_path(get_include_path() . APP_PATH . DIRECTORY_SEPARATOR . "models" . PATH_SEPARATOR . APP_PATH . DIRECTORY_SEPARATOR . "plugins"); // AutoLoad von Zend_Loader benutzen um Klassen zur Laufzeit hinzu zu laden require_once('Zend/Loader.php'); Zend_Loader::registerAutoload('Zend_Loader'); // Zend_Cache einrichten $frontendOptions = array('lifetime' => 7200, 'automatic_serialization' => true); $backendOptions = array('cache_dir' => $root . DIRECTORY_SEPARATOR . 'tmp'); $cache = Zend_Cache::factory('Page', 'File', $frontendOptions, $backendOptions); // Zend_Translate initialisieren Zend_Translate::setCache($cache); $translate = new Zend_Translate('gettext', APP_PATH . DIRECTORY_SEPARATOR . 'languages' . DIRECTORY_SEPARATOR . 'de_DE.mo', 'de_DE'); $translate->setLocale('de_DE'); // Mit Zend_Registry zentral registrieren: Zend_Registry::set('Zend_Translate',$translate); // Zend_Layout starten Zend_Layout::startMvc(array('layoutPath' => APP_PATH . DIRECTORY_SEPARATOR . 'layouts')); // Zend_Front_Controller dispatchen $view = Zend_Layout::getMvcInstance()->getView(); $view->baseUrl = '/'; Zend_Controller_Front::run(APP_PATH . DIRECTORY_SEPARATOR . 'controller');
Wie man sieht lasse ich auch hier den PHP-Abschluss weg (?>) und benutzte grundsätzlich anstelle von hardcodierten / oder \ den DIRECTORY_SEPARATOR da ich auch unter Windows mit XAMPP am coden bin.
Den /application/controller/IndexController halte ich ebenfalls sehr simpel für dieses Beispiel:
class IndexController extends Zend_Controller_Action { public function indexAction() { // Hier würde nun der Code-Syntax für die Index-Seite definiert... } }
Um das Beispiel recht einfach zu halten poste ich lediglich eine simple Layout-Variante um Zend_Translate zu demonstrieren:
/application/layouts/layout.phtml:
< ?= doctype(Zend_View_Helper_Doctype::XHTML1_TRANSITIONAL); ?> < ?= headTitle('Zend_Translate test'); ?> < ?= headLink()->appendStylesheet($this->baseUrl.'css/styles.css'); ?> < ?= headScript(); ?> <div id="page">< ?= layout()->content ?></div>
In der eigentlichen View der Index-Seite werden wir nun Translate einsetzen:
/application/views/scripts/index/index.phtml:
<h1>< ?= translate("Zend_Translate example") ?></h1> < ?= translate("This is an example of Zend_Translate") ?>
Die Ausgabe dürfte nun sein:
<div id="page"> <h1>Zend_Translate Beispiel</h1> Dies ist ein Beispiel von Zend_Translate </div>
Ich hoffe damit auch anderen Verzweifelnden mit Zend_Translate und Gettext etwas behilflich zu sein und freue mich – wie immer – auf Kommentare



