Eigene Joomla Komponente erstellen

Dieser Artikel beschreibt wie Sie eine individuelle Komponente für Joomla entwickeln können. Es gibt natürlich eine Vielzahl an Joomla-Erweiterungen, doch wenn Sie keine passende Erweiterung finden können, kann die Entwicklung einer eigenen Joomla Komponente unerlässlich sein.

Bei der Suche nach Joomla Erweiterungen und Komponenten werden Sie wahrcheinlich auf das Joomla Extension Directory gestoßen sein. Für viele Anwendungen sind Joomla Komponenten verfügbar, bei speziellen Anforderungen werden Sie jedoch um die Erstellung einer individuellen Joomla Komponente nicht herumkommen.

Sie benötigen professionelle Hilfe beim Erstellen einer Joomla Komponente? Gerne unterstützen wir Sie bei Ihrem Anliegen. Bitte nehmen Sie dafür Kontakt mit uns auf!

Dieser Artikel erklärt anschaulich das Erstellen einer Joomla Komponente. Dafür sind Grundkenntnisse in PHP und MySQL erforderlich. Die Idee hinter der Komponente ist es, Smartphones im Joomla Frontend anzueigen, als Liste mit mehreren Smartphones und individuelle Produktansicht. Natürlich könnte dieses Vorhaben mit bereits bestehenden Komponenten realisiert werden - es dient hier lediglich als Beispiel. Es ist ein Exempel das häufiger anzutreffen ist: So versuchen z.B. Affiliate Marketer Produktlisten bzw. Vergleichslisten zu erstellen, um bestimmte Produkte zu promoten. Ein anderes Beispiel wären Immobilien-Makler die ein Expose mit Immobilien und Häuser veröffentlichen wollen.

Ok, beginnen wir nun mit der Komponente. Vermutlich sind Sie bereits etwas mit der Joomla Ornderstruktur vertraut. Jede Joomla-Installation hat einen Ordner "components" in der wir unserer Komponente abspeichern. Daher legen wir im Ordner "components" einen Ordner mit dem Namen "com_smartphones" an. Darin erstellen wir eine Datei smartphones.php mit folgendem Inhalt:

<?php
echo 123;

Ok, das ist noch nicht besonders beeindruckend, aber ok für den ersten Schritt. Damit sollte lediglich "123" im Frontend ausgegeben werden. Wir wollen nun das Joomla Frontend auf eine Ausgabe überprüfen. Joomla-URLs sind typischerweise wie folgt aufgebaut: www.your-domain.de/index.php?option=com_smartphones - wenn Sie den Host anpassen und versuchen die Seite aufzurufen, sollte ein 404 Fehler auftreten mit der Nachricht, dass die Komponente nicht gefunden wurde.

Jooml verwaltet verfügbare Erweiterungen in der Datenbank. In der Tabelle prefix_extensions werden diese gespeichert. Bei der Installation von Joomla Komponenten wird der entsprechende Datenbank-Eintrag automatisch angelegt. In diesem Beispiel möchte ich den Eintrag jedoch manuell anlegen, so dass wir etwas mehr mit den Interna von Joomla Komponenten vertraut werden. Mit Hilfe von folgendem SQL-Statement (der Tabellen-Präfix jos_ muss evtl. angepasst werden!) kann die Komponente in der Datenbank hinzugefügt werden:

INSERT INTO `jos_extensions` (
   `name`, 
   `type`, 
   `element`, 
   `folder`, 
   `client_id`, 
   `params`, 
   `custom_data`, 
   `system_data`, 
   `manifest_cache`
) VALUES (
   'com_smartphones', 
   'component',
   'com_smartphones',
   '',
   0, 
   '',
   '',
   '',
   '{"name":"com_smartphones","type":"component"}'}'
);

Wenn Sie die Ausgabe im Joomla Frontend mit obigem Link erneut prüfen, sollte "123 " ausgegeben werden.

Grundlegende Ordnerstruktur und Dateien für die Joomla Komponente anlegen

Bei der Entwicklung von Webanwendungen wird häufig ein Prinzip namens MVC verwendet - Joomla verwendet ebenfalls die MVC-Struktur. Die Grundlegende Idee dahinter ist es, die Anwendung in 3 Bereiche aufzuteilen: Ein Model, welches als Schnittstelle zur Datenbank dient. Ein View der die Ausgabe im Frontend erzeugt sowie ein Controller der die Logik hinter der Komponente steuert. Eine Joomla Komponente sollte dem MVC-Prinzip aus verschiedenen Gründen folgen. Es wird nicht nur die Weiterentwicklung der Kopmonente vereinfacht sondern auch Optionen wie das Überrschreiben von Joomla-Templates werden hinzugefügt. Daher wird die Datei smartphones.php wie folgt angepasst:

<?php
defined('_JEXEC') or die;
$controller = JControllerLegacy::getInstance('Smartphones');
$controller->execute(JFactory::getApplication()->input->get('task'));
$controller->redirect(); 

Zunächst wird überprüft ob '_JECEX' definiert ist, sonst wird abgebrochen. Dies verinhidert dass die Datei außerhalb des Joomla-Kontexts aufgerufen wird und dient der Sicheheit. Beispielsweise war es zuvor möglich, die Datei direkt über www.your-domain.de/components/com_smartphones/smartphones.php aufzurufen. Weiter im Code wird ein Objekt der Klasse SmartphonesController erzeugt - diese Klasse definieren wir später. Die Klasse kann verschiedene Funktionen enthalten die über den task-Parameter abgerufen werden.

Als nächstes erzeugen wir eine Datei "controller.php" im "com_smartphones"-Ornderder. Diese Datei enthält die Klasse von der wir eben gesprochen haben:

<?php
defined('_JEXEC') or die;
class SmartphonesController extends JControllerLegacy {
}

Wiederum wird ein direkter Aufruf unterbunden. Die Klasse SmartphonesController wird definiert und erbt von der Klasse JLegacyController, beinhaltet jedoch keine Klassenvariablen oder -funktionen.

Wenn ich nun die Anzeige im Frontend aktualisiere, taucht eine Fehlermeldung auf mit dem Hinweis dass ein view namens "smartphones" nicht existiert. Daher erstelle ich im "com_smpartphones"-Ordner einen Ornder "views" und in diesem Ordner einen weiteren Ornder namens "smartphones". Darin wird die Datei view.html.php erzeugt mit dem folgenden Inhalt:

<?php
defined('_JEXEC') or die;
class SmartphonesViewSmartphones extends JViewLegacy {
}

Nach erneuter Überprüfung im Frontend erhalten wir nun die Nachricht, dass das Standard-Layout nicht definiert ist. Daher zeugen wir den Ordner "tmpl" im "smartphones"-View-Ornder und legen darin eine Datei default.php ab mit dem folgenden Inhalt:

<?php
defined('_JEXEC') or die;
echo 123;

Nun sollte wieder "123" im Frontend ausgegeben werden. Natürlich sind wir noch weit von unserem Vorhaben entfernt, dynamische Inhalte auszugeben, jedoch haben wir nun die Grundlegende Ordner- und Dateistruktur für eine eigene Joomla-Komponente erstellt.

Datenbank-Inhalte in der Joomla-Komponente anzeigen

Ich nehme an, dass die Daten für die Smartphones in einer Datenbanktabelle abgespeichert werden. Als Beispiel verwende ich das folgende SQL-Statement um eine Tabelle anzulegen und mit Beispieldaten zu füllen:

CREATE TABLE `jos_smartphones` (
 `id` int(11) NOT NULL,
 `name` varchar(255) NOT NULL,
 `manufacturer` varchar(255) NOT NULL,
 `price` float NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `jos_smartphones` (`id`, `name`, `manufacturer`, `price`) VALUES
 (1, 'TopPhone', 'ManufacturerA', 99)
 (2, 'CheapPhone', 'MassProuction', 14.99);
ALTER TABLE `jos_smartphones` ADD PRIMARY KEY (`id`);
ALTER TABLE `jos_smartphones` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;

Als nächstes wollen wir diese Daten im Joomla-Frontend anzeigen. Dazu modifizieren wir die Datei view.html.php:

<?php
defined('_JEXEC') or die;
class SmartphonesViewSmartphones extends JViewLegacy { 
 public function display($tpl = null){
 $this->smartphones = $this->get('Smartphones');
 parent::display($tpl);
 }
}

Eine Klassenfunktion mit dem Namen "display" wird erzeugt und darin eine Liste mit den Smartphones dem Attribut $this->smartphones zugewiesen. Die get-Funktion wird gleich in der Model-Datei definiert werden. Die Variable $this wird auch in der Ausgabedatei default.php verfügbar sein. Zuvor war die Funktion display nicht explizit definiert, es wurde auf Funktion display der Klasse JViewLegacy zurückgegriffen.

Wir erstellen nun einen Ornder "models" im Hauptverzeichnis der Komponente com_smartphones und legen eine Datei "smartphones.php" an mit dem folgenden Inhalt:

<?php
defined('_JEXEC') or die;
class SmartphonesModelSmartphones extends JModelList {
 public function getSmartphones() {
 $db = JFactory::getDBO();
 $query = $db->getQuery(true);
 $query->select('*');
 $query->from('#__smartphones');
 $db->setQuery((string) $query);
 $smartphones = $db->loadObjectList();
 return $smartphones;
 }
}

Unter Verwendung der Joomla API wird eine Datenbankverbindungs-Objekt erstellt und eine Abfrage ausgefürhrt. Die Smartphones werden als Array zurückgegeben. Im letzten Schritt wird die Ausgabedatei default.php wie folgt angepasst:

<?php
defined('_JEXEC') or die;
?>
<table>
 <?php foreach ($this->smartphones as $smartphone) { ?>
 <tr>
 <td width="300"><?php echo $smartphone->name; ?></td>
 <td width="300"><?php echo $smartphone->manufacturer; ?></td>
 <td width="300"><?php echo $smartphone->price; ?></td>
 </tr>
 <?php } ?>
</table>

Wenn das Frontend nun aktualisiert wird, sollte eine Tabelle mit den Datenbank-Inhalten ausgegeben werden. Damit wäre ein erstes Etappenziel erreicht, nämlich die Ausgabe von Datenbank-Inhalten im Joomla Frontend.

Als nächstes wollen wir noch eine weitere Ansicht (View) hinzufügen, bei der individuelle Smartphones gewissermaßen als Produkt-Seite angezeigt werden. Zunächst duplizieren wir einfach den Ornder "smartphones" im views-Verzeichnis und bennen das Duplikat um in "smartphone". Die Datei view.html.php in diesem Ornder wird wie folgt angepasst:

<?php
defined('_JEXEC') or die;
class SmartphonesViewSmartphones extends JViewLegacy { 
 public function display($tpl = null){
 $id = JFactory::getApplication()->input->getInt('id',0);
 $model = $this->getModel('smartphones');
 $this->smartphone = $model->getSmartphone($id);
 if(!isset($this->smartphone->name)){
 return JError::raiseError(403, 'ID not valid');
 }
 parent::display($tpl);
 }
}

Es erfolgt eine Abfrage für einen get Parameter namens "id". Der Eintrag für diese id wird dann aus der Datenbank geladen. Ein Fehler wird zurückgegeben falls kein Eintrag zu dieser id vorhanden ist. Um das zuvor angelegte Model innerhalb der neuen View-Klasse zu verwenden müssen wir das Model im Controller hinzufügen:

public function display($cachable = false, $urlparams = false) { 
 $viewName = $this->input->get('view', $this->default_view);
 if ($viewName == 'smartphone') { 
 $viewLayout = $this->input->get('layout', 'default'); 
 $view = $this->getView($viewName, 'html', '',
 array('base_path' => $this->basePath,
 'layout' => $viewLayout)); 
 $view->setModel($this->getModel('smartphones'), true); 
 } 
 parent::display($cachable, $urlparams); 
}

Außerdem müssen wir die Model-Datei um eine Funktion erweitern, die Smartphone-Daten für eine gegebene id zurückliefert:

public function getSmartphone($id){
    $db = JFactory::getDBO();
    $query = $db->getQuery(true);
    $query->select('*');
    $query->from('#__smartphones');
    $query->where('id='.$id);
    $db->setQuery((string) $query);
 $smartphones = $db->loadObject();
    return $smartphones;
}

Abschließend modifzieren wir die Layout-Datei und können beispielsweise den Namen des Smartphones via $this->smartphone->name ausgeben. Wenn die URL mit index.php?option=com_smartphones&view=smartphone&id=1 aufgerufen wird, sollte nun der Name des Smartphones mit id=1 ausgegeben werden.

Weitere Funktionen der Joomla-Komonente hinzufügen

Natürlich war das bisher lediglich eine kleine Einführung in das Entwickeln von Joomla Komponenten und die Komponente könnte auf vielfältige Weise weiterentwickelt werden: Denkbar wäre es z.B. einen Bereich im Backend hinzuzufügen um die Smartphone Daten bequem in einem Formular zu bearbeiten. Außerdem wäre es denkbar, Menüpunkte mit den Views anzulegen um die Komponente in die Seite zu integrieren. Auch die Entwicklung von Joomla Plugins oder die Erstellung von Joomla Modulen speziell für die Smartphones-Komponente wäre denkbar um die Funktionalität der Joomla-Webseite zu vergrößern.

Die Joomla API bietet eine Vielzahl an vor-implementierten Funktionen und Klassen, welche die Entwicklung von Komponenten vereinfachen. Beispielweise ist es problemlos möglich, verschiedene Rollen und Zugriffsrechte zu definieren, suchmaschinenfreundliche URLs zu verwenden oder Formulare zu erstellen. Der Funktionsumfang ist enorm und letztendlich lässt sich wohl so ziemlich jedes Vorhaben als Joomla Komponente realisieren.

Gerne unterstützen wir Sie bei der Entwicklung von Joomla Komponenten. Bitte nehmen Sie einfach Kontakt mit uns auf.