Benutzer:Elkuku/Proyektz/EVI2/JFishbone
Inhaltsverzeichnis |
[Bearbeiten] JFishbone - Eine Joomla! Anwendung
Was heißt das: Eine Joomla! Applikation?
Nun, Joomla! ist ein bekanntes Content Management System, aber seit Version 1.5 ist es mehr als nur eine schnell einzusetzende CMS-Anwendung. Joomla! stellt ein Framework für PHP-Entwickler bereit, die ihre eigenen Anwendungen mit der ganzen Vielfalt an Features, wie den Einsatz von Templates, einfachen Datenbankzugriff, eine Verwaltungsschnittstelle, Komponenten und Module, und Nutzer und Kontakt-Management ausstatten wollen.
Um zu zeigen, wie all das funktioniert, habe ich eine kleine Anwendung names Fishbone entwickelt, welche zeigt, wie man das Framework nutzt und wie man solch eine Anwendung strukturiert. Der gesamte Beispielcode stammt von Joomla!, hauptsächlich aus dem Installations- und Administrationsbereich des CMS.
In unserem Beispiel nutzen wir ein Template, um einfache Textausgaben und die Unterstützung verschiedener Sprachen zu demonstrieren.
[Bearbeiten] Die Struktur der Anwendung
Der Name der Anwendung ist Fishbone, also ist unsere erste Aufgabe die Erstellung eines Verzeichnisses mit diesem Namen. Das Verzeichnis definiert den Startpunkt der Anwendung und enthält die Hauptdatei
index.php, welche die Bibliotheken lädt und das Anwendungsobjekt ausführt.
Wenn Sie Joomla! auf Ihrem lokalen Rechner im Verzeichnis
joomla15 installiert haben, können Sie Fishbone folgendermassen aufrufen.
http://localhost/joomla15/fishbone
[Bearbeiten] index.php
Schauen wir uns die
index.php an:
/** * Fishbone - a Joomla! Application * created by Wolfgang Disch */ define( '_JEXEC', 1 ); define( 'JPATH_BASE', dirname( __FILE__ ) ); define( 'DS', DIRECTORY_SEPARATOR ); require_once ( JPATH_BASE .DS.'includes'.DS.'defines.php' ); require_once ( JPATH_BASE .DS.'includes'.DS.'framework.php' ); /* create the mainframe object */ $mainframe =& JFactory::getApplication('fishbone'); /* initialise the application */ $mainframe->initialise(); /* render the application */ $mainframe->render(); /* return the response */ echo JResponse::toString();
Anhand dieser Datei können wir die Struktur einer Joomla! Anwendung sehen: Das Anwendungsverzeichnis beinhaltet ein Verzeichnis mit dem Namen
includes, welches die anwendungsbezogenen Dateien
defines.php,
framework.php,
application.php und andere beinhaltet.
[Bearbeiten] defines.php
Die Datei
defines.php spezifiziert die global genutzten Dateipfade:
// no direct access defined( '_JEXEC' ) or die( 'Restricted access' ); /* Joomla framework path definitions */ $parts = explode( DS, JPATH_BASE ); array_pop( $parts ); define( 'JPATH_ROOT', implode( DS, $parts ) ); define( 'JPATH_SITE', JPATH_ROOT ); define( 'JPATH_CONFIGURATION', JPATH_ROOT ); define( 'JPATH_ADMINISTRATOR', JPATH_ROOT.DS.'administrator' ); define( 'JPATH_XMLRPC', JPATH_ROOT.DS.'xmlrpc' ); define( 'JPATH_LIBRARIES', JPATH_ROOT.DS.'libraries' ); define( 'JPATH_PLUGINS', JPATH_ROOT.DS.'plugins' ); define( 'JPATH_INSTALLATION', JPATH_ROOT.DS.'installation' ); define( 'JPATH_THEMES', JPATH_BASE.DS.'templates' ); define( 'JPATH_CACHE', JPATH_ROOT.DS.'cache' ); /* the new application */ define( 'JPATH_FISHBONE', JPATH_ROOT.DS.'fishbone' );
[Bearbeiten] framework.php
In der
framework.php werden die Framework bezogenen Dateien geladen:
// no direct access defined( '_JEXEC' ) or die( 'Restricted access' ); /* * Joomla! system checks */ error_reporting( E_ALL ); @set_magic_quotes_runtime( 0 ); @ini_set('zend.ze1_compatibility_mode', '0'); /* * Joomla! system startup */ // System includes require_once( JPATH_LIBRARIES.DS.'joomla'.DS.'import.php'); // Installation file includes define( 'JPATH_INCLUDES', dirname(__FILE__) ); /* * Joomla! framework loading */ // Include object abstract class require_once(JPATH_SITE.DS.'libraries'.DS.'joomla'.DS.'utilities'.DS.'compat'.DS.'compat.php'); // Joomla! library imports jimport( 'joomla.database.table' ); jimport( 'joomla.user.user'); jimport( 'joomla.environment.uri' ); jimport( 'joomla.user.user'); jimport( 'joomla.html.parameter' ); jimport( 'joomla.utilities.utility' ); jimport( 'joomla.language.language'); jimport( 'joomla.utilities.string' );
Zurück in der
index.php sehen wir, wie die Anwendung erzeugt wird:
// create the mainframe object $mainframe =& JFactory::getApplication('fishbone');
[Bearbeiten] application.php
Die Factory Klasse sucht im
/fishbone/includes Verzeichnis nach einer Datei names
application.php. Diese Datei enthält das JFishbone Objekt, das die Klasse JApplication erweitert. Hier ist der Konstruktor der Klasse:
// no direct access defined( '_JEXEC' ) or die('Restricted access' ); /** * Joomla! Application class * * @final */ class JFishbone extends JApplication { /** * Class constructor * * @access protected * @param array An optional associative array of * configuration settings * Recognized key values include 'clientId' * (this list is not meant to be comprehensive). */ function __construct($config = array()) { // OUR APPLICATION ID $config['clientId'] = 4; parent::__construct($config); //Set the root in the URI based on the application name JURI::root(null, str_replace('/'.$this->getName(), '', JURI::base(true))); }
Er definiert eine client ID für unsere Anwendung. Aber die Erstellung der neuen Instanz wird fehlschlagen! Dies liegt daran, dass tief in der JApplication Klasse ein Aufruf zu einer Helper-Klasse stattfindet:
$info =& JApplicationHelper::getClientInfo($client, true);
Der Sinn dieses Aufrufs ist, Informationen zu registrierten Anwenungen zu erlangen. Grundsätzlich sind vier Anwenungen in der JApplicationHelper Klasse bereits vorhanden, das wären der Website-Client, der Administrations-Client, der Installations-Client und XMLRPC-Client. Wir könnten nun unsere Anwendung einfach hinter die bereits Vorhandenen anhängen. Das wäre allerdings ein Hack der JApplicationHelper Klasse. Um das zu vermeiden, registrieren wir unsere Anwendung einfach in der
index.php, indem wir ein weiteres Client-Objekt an das Client-Array anfügen:
/** * Fishbone - a Joomla! Application * created by Wolfgang Disch */ define( '_JEXEC', 1 ); define( 'JPATH_BASE', dirname( __FILE__ ) ); define( 'DS', DIRECTORY_SEPARATOR ); require_once ( JPATH_BASE .DS.'includes'.DS.'defines.php' ); require_once ( JPATH_BASE .DS.'includes'.DS.'framework.php' ); jimport( 'joomla.application.helper' ); $info =& JApplicationHelper::getClientInfo(); $obj = new stdClass(); $obj->id = 4; $obj->name = 'fishbone'; $obj->path = JPATH_FISHBONE; $info[4] = $obj; unset($obj); // create the mainframe object $mainframe =& JFactory::getApplication('fishbone'); // initialise the application $mainframe->initialise(array('language' => 'de-DE')); // render the application $mainframe->render(); // return the response echo JResponse::toString();
Nun kann unsere Anwendung registriert werden, und die Erzeugung des Anwendungsobjekts ist erfolgreich.
[Bearbeiten] Der Anwendungsfluss
Nun wird der Anwendungsfluss ausgeführt: Nach dem Erstellen des Objektes durch die Factory Klasse JFactory werden die Methoden initialise() und render() ausgeführt. Es gibt weitere Methoden für das Routing (Erzeugung von URLs) und Dispatching (Handhabung von Ereignissen), aber wir wollen es einfach halten.
Die Initialisierungsmethode setzt die Sprache der Anwendung:
/** * Initialise the application. * * @access public */ function initialise( $options = array()) { // Give the user English if (!empty($options['language'])) { $options['language'] = 'en-GB'; } // One last check to make sure we have something if ( ! JLanguage::exists($options['language']) ) { $options['language'] = 'en-GB'; } parent::initialise($options); }
In unserem Beispiel wechseln wir zur Deutschen Sprache, wenn wir die Methode mit einem Sprachparameter aufrufen:
// initialise the application $mainframe->initialise(array('language' => 'de-DE'));
Nun folgt der Kern der Anwendung. Die $mainframe->render Methode lädt das Template und rendert es. Das Ergebnis wird in den Body des JResponse-Objekts geschrieben. Der Name und Pfad des Templates werden der Render-Methode des Dokuments, welches vom Typ JDocumentHTML ist, übergeben.
$params = array( 'template' => 'default', 'file' => 'index.php', 'directory' => JPATH_THEMES ); $data = $document->render(false, $params); JResponse::setBody($data);
Das Rendern des Templates ersetzt Ausdrücke durch den Inhalt der genannten Komponente ('component'), welche durch die setBuffer Methode gesetzt wird.
$document->setBuffer( $contents, 'component');
Hier sehen wir die Aufteilung in Template auf der einen, und Komponente auf der anderen Seite. Um das Beispiel einfach zu halten, wird der Inhalt direkt von einer Pseudo-Komponente gesetzt, welche wir in die Render-Methode einbeziehen.
Schauen wir uns nun die Render-Methode an:
/** * Render the application * * @access public */ function render() { $document =& JFactory::getDocument(); $user =& JFactory::getUser(); $document->setTitle(JText::_('PAGE_TITLE')); // Define component path define('JPATH_COMPONENT', JPATH_BASE.DS.'content'); // Execute the component ob_start(); require_once(JPATH_COMPONENT.DS.'hello.php'); $contents = ob_get_contents(); ob_end_clean(); $params = array( 'template' => 'default', 'file' => 'index.php', 'directory' => JPATH_THEMES ); $document->setBuffer( $contents, 'component'); $data = $document->render(false, $params); JResponse::setBody($data); }
Die Komponente in
hello.php ist nur ein Platzhalter, um zu demonstrieren, wie die Anwendung verschiedene Komponenten einsetzen kann, um Inhalte in das Template zu rendern.
Der Inhalt wird schließlich $contents zugewiesen.
Nach dem Rendern des Inhalts der Seite wird das Ergebnis dem JResponse-Objekt angefügt. In der letzten Zeile wird JResponse ausgegeben.
// return the response echo JResponse::toString();
Das war's. Die kompletten Dateien finden sie im Download (siehe unten). Dort sind dann auch die Verzeichnisse "content", "templates" und "language" enhalten, die fishbone erst anwenden lassen.
Das Ergebnis sieht sehr einfach aus, aber Sie sollten daran denken, was wir erreicht haben:
Wir haben eine Anwendung mit voller Unterstützung des Joomla! Frameworks entwickelt
- Wir nutzen JDocument, JDocumentHTML und deren verwandte Methoden, um das Dokument zu rendern.
- Wir nutzen ein Template, welches einfach verändert werden kann, ohne den Code anzufassen.
- Wir haben bereits eine Unterstützung für Mehrsprachigkeit, welche erweitert werden kann, um zwischen den Sprachen umzuschalten.
- Wir haben das Komponenten-Konzept eingeführt.
[Bearbeiten] Quellen
Der Originalartikel stammt von Wolfgang Disch und wurde im JFoobar Blog veröffentlicht. Die Übersetzung und Veröffentlichung dieses Artikels wurde offiziell genemigt. Für ein besseres Verständnis wurden kleine Anpassungen und ein paar klärende Sätze eingefügt.
Die deutsche Übersetzung stammt von Tom Bohaĉek und wurde hier nach freundlicher Genehmigung von Ihm übernommen.
- http://www.bohacek.de/b01-joomla-blog/jfishbone-eine-joomla-anwendung.html
- Hier finden Sie auch den Download
