29 Komponenten entwickeln
Komponenten sind die universellsten unter den Erweiterungen und agieren wie kleine Miniapplikationen mit eigener Benutzeroberfläche und Zugriff auf das Framework und Inhaltselemente.
Komponenten treffen Sie sowohl in der Joomla!-Core als auch über das Menü Komponenten an, denn sie übernehmen eine Unzahl wichtiger Aufgaben, angefangen von der Beitragsverwaltung über das Benutzerrechte-Management oder die Kategorieorganisation bis hin zu Suchmaschinenoptimierung und Import-/Export-Funktionalitäten. Es gibt reine Backend-Komponenten für die Websiteadministration oder Kombinationen für Backend und Frontend, in denen Sie Inhalte einpflegen, um sie Websitebesuchern zu präsentieren. Im sichtbaren Bereich des Administrations-Backends haben jedoch alle Komponenten eines gemeinsam: die Benutzeroberfläche, die Sie von vielen Funktionalitäten kennen, seien es Beiträge, Menüeinträge, Umleitungen, Kunena-Kategorien, Phoca-Download-Dateien oder OSMap-Sitemaps. Meist enthält sie eine Liste von über Spaltenüberschriften sortierbaren Elementen und eine Buttonleiste, die mindestens die Standardbuttons Neu, Bearbeiten und Löschen enthält. Ferner steht ein Formular zur Bearbeitung eines einzelnen Elements zur Verfügung, die Einzelansicht. Diese und viele weitere Bausteine stellt das Joomla!-Framework von Grund auf zur Verfügung, sodass Sie Ihre Komponente nahtlos in das Content-Management-System und seine Benutzeroberfläche integrieren können.
In diesem Kapitel bauen Sie Schritt für Schritt eine typische Joomla!-Komponente auf, mit der der Webmaster Elemente eines neuen Inhaltstyps verwaltet, ähnlich wie Beiträge, Phoca Gallerys Bilder oder Kunenas Forenkategorien (siehe Abbildung 29.1). Die einzelnen Schritte:
-
Komponentengerüst und Listenansicht von Inhaltselementen
-
Detailansicht, ein Formular zur Neuanlage oder zum Bearbeiten einzelner Inhaltselemente
-
Frontend-Komponente, die die Inhaltselemente auf Webseiten listet
-
ergänzende Erweiterungen der Backend-Komponente wie Seitenleiste und Konfigurationsformular
Im Verlauf der Entwicklung entstehen dabei zahlreiche PHP- und XML-Dateien, idealer Nährboden für Tippfehler. Darum haben Sie die Möglichkeit, unter https://joomla-handbuch.com/downloads/handbuch Komponentenpakete für jeden Schritt herunterzuladen, die Komponente zu installieren und die einzelnen Dateien anhand ihrer Besprechung auf diesen Seiten zu studieren. Sie erfahren, welche Dateien welche Rolle spielen, und lernen die interessantesten Highlights des Codes kennen. Übrigens: Unter http://development.joomla-handbuch.com sehen Sie die in diesem Kapitel entwickelte Komponente im Live-Einsatz.
Tipp: Für die Komponentenprogrammierung richten Sie sich besser eine IDE, eine integrierte Entwicklungsumgebung, ein, da das die Fehlersuche bei der großen Anzahl involvierter Programmdateien erheblich beschleunigt.
29.1 Backend-Komponente mit Listenansicht anlegen
Im ersten Schritt lernen Sie die Erzeugung einer reinen Backend-Komponente mit Listenansicht. Die Urlaubsziele des Reiseforums dienen als Beispiel für die zu verwaltenden Inhaltselemente, darum trägt die Erweiterung den schlichten Namen Location bzw. programmintern com_location (siehe Abbildung 29.2).
Ziel: Sie erzeugen das Komponentengerüst und eine Listenansicht einer Backend-Komponente für das neue Inhaltselement Urlaubsziele bzw. Locations (programmintern locations).
Vorgehen: Sie legen nacheinander die einzelnen Model-View-Controller-Dateien an und konstruieren so den Weg von der Anfrage an die Komponente über die Datenbankabfragen und -aktualisierungen bis zur Ausgabe ins Template-Layout. Zuvor bereiten Sie die Komponentenumgebung über das XML-Manifest und die Erweiterung der Datenbank vor.
Hinweis: Ab hier können Sie die neue Komponente entweder per Hand direkt in Ihrem Joomla!-Entwicklungssystem aufbauen, indem Sie alle Listings abtippen. Oder Sie laden sich das Paket com_location_v0.1.0.zip von https://joomla-handbuch.com/downloads/handbuch herunter, installieren es über Erweiterungen • Verwalten • Seitenleiste Installieren • Reiter Paketdatei hochladen und studieren die einzelnen Dateien anhand der Erklärungen in diesem Kapitel. Verschaffen Sie sich zunächst anhand der folgenden Tabelle einen Überblick über die involvierten Dateien (index.html-Dateien für den Serververzeichnisschutz sind obligatorisch und in der Liste nicht erwähnt).
Verzeichnis/Datei | Aufgabe |
---|---|
controller.php | Haupt-Controller der Komponente zum Aufruf der View-abhängigen Unter-Controller |
location.php | Komponenten-Einstiegsdatei für Joomla!, Initialisierung des Haupt-Controllers |
location.xml | XML-Manifest |
/controllers/ | Verzeichnis für alle Unter-Controller |
locations.php | View-Controller für die Listenansicht |
/language/ | Enthält alle Sprachdateien. |
/en-GB/ | englischsprachiges Standardverzeichnis |
en-GB.com_location.ini | Sprachdatei für alle Beschriftungen während der Laufzeit |
en-GB.com_location.sys.ini | Sprachdatei für Beschriftungen während der Installation |
/models/ | Enthält alle Komponenten-Models. |
locations.php | Model für die Listenansicht |
/sql/ | Enthält Datenbankscripts. |
0.1.0.sql | Historie der Datenbankscripts |
install.mysql.utf8.sql | Tabellenerzeugung während der Installation |
uninstall.mysql.utf8.sql | Datenbankbereinigung bei Deinstallation |
/views/ | Enthält Businesslogik und HTML-Template aller Views. |
/locations/ | Enthält den View der Listenansicht. |
view.html.php | Businesslogik der Listenansicht |
/tmpl/ | Enthält HTML-Templates. |
default.php | HTML-Template der Listenansicht |
Hinweis: Vorausgesetzte Regeln bei der Komponentenprogrammierung
Wie in den vergangenen Kapiteln über Plugins und Module gilt auch für Komponenten:
-
In jedes Verzeichnis gehört aus Sicherheitsgründen eine aus den Tags <html><body></body></html> bestehende index.html-Datei. Im weiteren Verlauf dieses Kapitels werden diese Dateien nicht mehr erwähnt.
-
Jede PHP-Datei beginnt mit der Anweisung defined('_JEXEC') or die;, damit das Script niemals außerhalb des Joomla!-Kontexts aufgerufen werden kann.
-
Verwenden Sie keine Shorttags <?.
-
Endet eine Datei mit PHP-Code, lassen Sie das Endtag ?> aus.
29.1.1 XML-Manifest – »location.xml«
Auch Komponenten sammeln all Ihre Meta-Informationen (Name, Versionsnummer, Kontakt- und Copyright-Hinweise, enthaltene Dateien etc.) in einer übergeordneten XML-Datei, die vor allem für die Installation und Deinstallation der Komponente entscheidend ist.
Falls Sie den Weg einer händischen Entwicklung gehen, erzeugen Sie in Ihrem Joomla!-Entwicklungssystem das Verzeichnis /administrator/components/com_location/ und darin die Datei location.xml. location ist die interne Bezeichnung für die neue Komponente, die in mehreren Dateinamen enthalten sein wird.
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="3.0" method="upgrade">
<name>com_location</name>
<author>Vorname Nachname</author>
<creationDate>May 2015</creationDate>
<copyright>(C) 2015 Vorname Nachname. All right reserved</copyright>
<license>GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html</license>
<authorEmail>Vorname.NachName@IhrDomainName.de</authorEmail>
<authorUrl>http://IhrDomainName.de</authorUrl>
<version>0.1.0</version>
<description>COM_LOCATION_XML_DESCRIPTION</description>
<install>
<sql>
<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
</sql>
</install>
<uninstall>
<sql>
<file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
</sql>
</uninstall>
<administration>
<menu>COM_LOCATION_MENU</menu>
<files folder="admin">
<filename>index.html</filename>
<filename>controller.php</filename>
<filename>location.php</filename>
<folder>controllers</folder>
<folder>models</folder>
<folder>sql</folder>
<folder>views</folder>
</files>
<languages folder="admin">
<language tag="en-GB">language/en-GB/en-GB.com_location.ini</language>
<language tag="en-GB">language/en-GB/en-GB.com_location.sys.ini
</language>
</languages>
</administration>
</extension>
Die im Listing hervorgehobenen Unterschiede zu den XML-Manifesten, die Sie aus der Plugin- und Modulentwicklung kennen, bestehen aus:
-
<extension type="component" […]>: Statt template, plugin oder module lautet der Erweiterungstyp component.
-
Die Locations-Komponente wird von vornherein mit übersetzbaren Sprachdateien angelegt (siehe Abschnitt 29.1.7, »Sprachdateien – »/language/en-GB/en-GB.com_location.(sys.)ini«), daher enthalten alle Quelltexte entsprechende Sprachschlüssel, wie z. B. hier COM_LOCATION_XML_DESCRIPTION für die Beschreibung der Komponente.
-
<install><sql> […] </sql></uninstall>: Die meisten Komponenten, so auch com_location, speichern Inhalte in ein oder mehreren Datenbanktabellen. Der <install>-Block verweist auf SQL-Scripts zur Erzeugung der notwendigen Tabellen; der <uninstall>-Block enthält DROP-TABLE-Anweisungen zum Bereinigen der Datenbank bei Komponentendeinstallation.
-
<menu>: Komponenten erhalten in der Regel einen Eintrag im Menü Komponenten, das <menu>-Tag enthält die Beschriftung; auch hier als Sprachschlüsselverweis.
-
<files> […] </files>: Auflistung aller für die Komponente erforderlichen Dateien und Verzeichnisse
-
controller.php: Haupt-Controller der Komponente
-
location.php: Einstiegspunkt für die Komponente, die den Haupt-Controller erzeugt und ihm seine Aufgabe übermittelt
-
controllers: Verzeichnis für weitere Controller, z. B. für die Steuerung der Ausgaben in der Listendarstellung der Locations
-
models: verschachtelte Verzeichnisse, die alle Dateien der Datenbankschicht enthalten
-
sql: Installations- und Deinstallationsscripts zur Erweiterung und Bereinigung der Datenbank
-
views: verschachteltes Verzeichnis für alle die Ausgabe betreffende Dateien, z. B. den Logikteil der Ausgabe in view.html.php und das HTML-Template default.php
-
Beachten Sie, dass XML-Manifeste von Komponenten keinen <config>-Block enthalten. Komponentenkonfigurationen sind im Backend von Joomla! unter System • Konfiguration • Seitenleiste Komponentenname hinterlegt, zu ihrer Erzeugung benötigen Sie eine zusätzliche Datei config.xml (siehe Abschnitt 29.4.2, »Konfigurationsseite und Berechtigungskonfiguration ergänzen«).
29.1.2 Datenbankscripts
Die Urlaubszielkomponente wird die über das Backend-Formular eingegebenen Locations in einer eigenen Datenbanktabelle speichern, über die sie exklusiv verfügt. Deshalb ist die Komponente auch für die Erzeugung der Tabelle während der Installation und für das Entfernen bei Deinstallation verantwortlich. Das erledigen die folgenden beiden SQL-Scripts im Verzeichnis /administrator/components/com_location/sql/, ihre Namen: install.mysql.utf8.sql und uninstall.mysql.utf8.sql.
CREATE TABLE IF NOT EXISTS `#__location` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL DEFAULT '',
`introtext` mediumtext NOT NULL DEFAULT '',
`photo` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
Das Installationsscript erstellt die Tabelle nur dann, falls sie noch nicht existiert (IF NOT EXISTS), und erzeugt dann Felder für die ID, den Urlaubszieltitel, einen kleinen Beschreibungstext und ein Textfeld zur Aufnahme eines Bildpfads. Achten Sie auf den Tabellennamen #__location (mit zwei Unterstrichen). Joomla! ersetzt Hash-Zeichen und ersten Unterstrich #_ automatisch durch das tatsächliche Präfix, das alle Tabellen während der Installation erhielten.
DROP TABLE IF EXISTS `#__location`;
Das Deinstallationsscript ist unkompliziert, die Tabelle wird kurzerhand gelöscht.
Falls Sie die Location-Komponente nicht installiert haben, sondern per Hand in Ihrem Entwicklungssystem nachbauen, ist es mit dem Anlegen dieser beiden Scripts nicht getan, denn die Datenbankaktualisierung erfolgt, wenn der Erweiterungsmanager die Komponente einrichtet.
Daher ist es jetzt erforderlich, die SQL-Anweisung manuell in phpMyAdmin auszuführen, indem Sie die CREATE TABLE-Anweisung in das Textfeld im SQL-Reiter kopieren (siehe Abbildung 29.3 ). Achtung: Ersetzen Sie dabei das Hash- und Unterstrichpräfix #_ durch Ihr tatsächliches Tabellenpräfix, das Sie über System • Konfiguration • Reiter Server • Bereich Datenbank • Feld Präfix erfahren; zwischen Präfix und Tabellenname location gehört ein einzelner Unterstrich.
29.1.3 Einstiegsdatei – »location.php«
Die einzige PHP-Datei, die Joomla! bei Aktivierung der Komponente direkt aufruft, trägt den Namen location.php und liegt im Komponentenverzeichnis unter /administrator/components/com_location/. Ab hier übergibt das Content-Management-System die Kontrolle an die Komponente.
<?php
defined('_JEXEC') or die;
if (!JFactory::getUser()->authorise('core.manage', 'com_location'))
{
return JFactory::getApplication()->enqueueMessage(JText::_('JERROR_
ALERTNOAUTHOR'), 'error');
}
$controller = JControllerLegacy::getInstance('Location');
$controller->execute(JFactory::getApplication()->input->get('task'));
$controller->redirect();
Nach dem obligatorischen PHP-Notausstieg folgt eine weitere Sicherheitsmaßnahme. Die Komponente com_location darf nur ausgeführt werden, wenn der aktuelle Benutzer Managerrechte besitzt, ansonsten erscheint eine Fehlermeldung. Die übrigen drei Zeilen initialisieren und starten den Komponenten-Controller. Beachten Sie den Parameter Location bei der Initialisierung; die Zeichenkette ist in genau dieser Schreibweise Identifikationsmerkmal für alle Klassen und Präfix für ihre Namen, z. B. class LocationModelLocations oder class LocationHelper.
29.1.4 Controller – »controller.php« und »locations.php«
Controller sind das Bindeglied zwischen der von Joomla! weitergeleiteten Benutzeranfrage und den Komponentenaktionen und -anzeigen. Dabei gibt es einen Haupt-Controller für die gesamte Komponente (links in Abbildung 29.4) sowie einzelne Unter-Controller pro View, also für die Listen- und später die Einzeldarstellung der Urlaubsziele (der hervorgehobene dunkelgraue rechte Bereich in Abbildung 29.4). Nur sie sind in der Lage, mit Daten umzugehen, während der Haupt-Controller für die Initialisierung der Anzeige zuständig ist.
Komponenten-Controller – »controller.php«
Durch die Einstiegs-PHP-Datei erfolgt der Aufruf des Komponenten-Controllers. Er heißt immer controller.php und liegt im Komponentenverzeichnis unter /administrator/components/com_location/. Beachten Sie den Namen der Elternklasse, von dem der Controller alle Eigenschaften und Methoden erbt, JControllerLegacy, also die Variante aus dem alten, aber trotzdem aktuellen Joomla!-Framework.
<?php
defined('_JEXEC') or die;
class LocationController extends JControllerLegacy
{
protected $default_view = 'locations';
public function display($cachable = false, $urlparams = false)
{
$view = $this->input->get('view', 'locations');
$layout = $this->input->get('layout', 'default');
$id = $this->input->getInt('id');
parent::display();
return $this;
}
}
$default_view enthält die Ansicht, die erscheint, wenn die Komponente ohne View-Angabe aufgerufen wird. Lassen Sie diese Anweisung weg, versucht Joomla!, den Komponentennamen als Ansicht aufzurufen. Im Fall der Urlaubsziele macht das keinen Sinn, da eine Übersicht über alle Locations erscheinen soll, also erhält die Variable die Pluralbezeichnung locations.
Die Funktion display() ist die aufgerufene Standardfunktion, falls der Controller keine andere Aufgabe erhält, und erlaubt den direkten Eingriff in die Steuerung des Controllers. Die ersten drei Zeilen holen sich deshalb den view, das layout und die id, falls vorhanden, aus den URL-Parametern und speichern sie zwischen. Dies ist vorbereitender Code, denn an dieser Stelle können Sie später gezielt Anweisungen ausführen, falls eine bestimmte View- und Layoutkombination aufgerufen wird. In diesem Beispiel passiert tatsächlich nichts anderes als die Kommandorückgabe an die vererbte Funktion, die den übrigen Code zur Darstellung und damit den Aufruf der View-individuellen Controller ausführt. (Falls Sie interessiert, wie der JControllerLegacy sein übriges Tagewerk verrichtet, studieren Sie ihn im Verzeichnis /libraries/legacy/controller/, Datei legacy.php.)
Weiter geht es mit dem Listenansicht-View-Controller, der, vom Haupt-Controller abgespaltet, die Steuerung des Views der Übersichtsliste (locations, Plural) übernimmt.
Listenansicht-Controller – »/controllers/locations.php«
Der Unter-Controller locations.php verknüpft alle Bestandteile der Listenansicht der Urlaubsziele und liegt in einem eigens dafür angelegten Unterverzeichnis /controllers/.
<?php
defined('_JEXEC') or die;
class LocationControllerLocations extends JControllerAdmin
{
public function getModel($name = 'Location', $prefix =
'LocationModel', $config = array('ignore_request' => true))
{
$model = parent::getModel($name, $prefix, $config);
return $model;
}
}
Zur Darstellung der Listenansicht ist bereits die Standardausführung des Controllers fähig. An dieser Stelle erfolgt aber bereits eine Vorbereitung für die später geplante Detailansicht der Locations. Denn der Controller ist hilflos, wenn es um Detailoperationen an den Urlaubszielen geht, die Sie in der Regel in Form von Buttons oberhalb der Listendarstellung sehen. Daher erbt der Listen-Controller von einer besonderen Joomla!-Klasse, die solche Operationen ermöglicht, vom JControllerAdmin, und stellt das Model für den Einzeleintrag einer Location bereit.
29.1.5 Model – »locations.php«
Das Model ist die Schnittstelle zur Datenbank, die das Lesen und Schreiben von Datensätzen ermöglicht, in Abbildung 29.5 dunkelgrau hervorgehoben sehen Sie das Model für die Listenansicht.
Listenansicht-Model – »/models/locations.php«
Für die Model-Programmierung der Locations-Liste sind SQL-Kenntnisse hilfreich, denn im Kern erfolgt hier eine Datenbankabfrage in spezieller Joomla!-Framework-Schreibweise. Das Listenansicht-Model liegt unter /administrator/components/com_location/models/ und trägt den Pluralnamen locations.php.
<?php
defined('_JEXEC') or die;
class LocationModelLocations extends JModelList
{
protected function getListQuery()
{
$db = $this->getDbo();
$query = $db->getQuery(true);
$query->select($db->quoteName(array('id', 'title', 'introtext',
'photo')));
$query->from($db->quoteName('#__location'));
return $query;
}
}
Die Funktion getListQuery() bezieht alle Locations aus der location-Tabelle. Dabei bauen Sie in der Variablen $query die Datenbankabfrage Schritt für Schritt auf: Per select listen Sie die zurückzugebenden Tabellenfelder aus der über from angegebenen Tabelle. In SQL ausgeschrieben, lautet die Abfrage:
SELECT 'id', 'title', 'introtext', 'photo' FROM #__location;
Das Model holt sich also die ID, den Titel, Beschreibungstext und den Fotolink, genau die Elemente, die später die Urlaubszielliste anzeigt.
29.1.6 View – »view.html.php« und »default.php«
Views bestehen aus mindestens zwei Bestandteilen, um die Businesslogik vom eigentlichen HTML-Template zu trennen: In view.html.php erfolgt die Aufbereitung der zur Ausgabe anstehenden Daten, außerdem werden hier Werkzeugleisten und Seitenleisten konstruiert. HTML-Code und Templateplatzhalter liegen in der Datei default.php.
View für die Listenansicht – »/views/locations/view.html«
Der Businesslogik-Teil des Views für die Listenausgabe liegt im Verzeichnis /administrator/components/com_location/views/locations/ und heißt view.html.php (dunkelgrau hervorgehoben in Abbildung 29.6).
<?php
defined('_JEXEC') or die;
class LocationViewLocations extends JViewLegacy
{
protected $locations;
public function display($tpl = null)
{
$this->locations = $this->get('Items');
$bar = JToolBar::getInstance('toolbar');
JToolbarHelper::title(JText::_('COM_LOCATION_MANAGER_LOCATIONS'), '');
JToolbarHelper::addNew('location.add');
JToolbarHelper::editList('location.edit');
JToolbarHelper::deleteList(JText::_('COM_LOCATION_DELETE_
CONFIRMATION'), 'locations.delete', 'JTOOLBAR_DELETE');
parent::display($tpl);
}
}
Im ersten Schritt holt sich der View mit $this->get('Items'); alle Daten aus dem Model und stellt sie dem HTML-Template in der Variablen getListQuery() zur Verfügung. Später sind dann alle Urlaubsziele mit ihren Detaildaten über die Variable $locations erreichbar. Die übrigen Anweisungen dienen zur Konstruktion der oberen Buttonleiste, die die Buttons Neu (location.add), Bearbeiten (location.edit) und Löschen (locations.delete) enthält. location bezieht sich dabei auf Aktionen einzelner Locations (Detailansicht), deren Implementierung im zweiten Schritt erfolgt – im Unterschied zu locations bei der Löschen-Button-Zuweisung, da diese Funktion auf mehrere, zuvor per Häkchen markierte Locations angewendet werden kann. Übrigens werden in der Komponente natürlich keine Textausgaben hardgecodet, daher sind an dieser Stelle Sprachschlüssel (COM_LOCATION_MANAGER_LOCATIONS, COM_LOCATION_DELETE_CONFIRMATION) enthalten, deren Inhalte später in einer Sprachdatei eingepflegt werden.
HTML-Template für die Listenansicht – »/views/locations/tmpl/default.php«
Am Ende des langen Wegs der Locations-Listendaten steht nun endlich das HTML-Template (dunkelgrau hervorgehoben in Abbildung 29.7). Wie andere Joomla!-Templates enthält es eine Mischung aus HTML-Tags und PHP-Befehlen, die als Platzhalter der zu injizierenden Daten dienen.
<?php
defined('_JEXEC') or die;
?>
<form action="<?php echo JRoute::_('index.php?option=com_location&view=
locations'); ?>" method="post" name="adminForm" id="adminForm">
<div id="j-main-container">
<div class="clearfix"> </div>
<table class="table table-striped" id="locationList">
<thead>
<tr>
<th width="1%" class="nowrap center hidden-phone">
<input type="checkbox" name="checkall-toggle" value="" title="
<?php echo JText::_('JGLOBAL_CHECK_ALL'); ?>" onclick=
"Joomla.checkAll(this);" />
</th>
<th>
<?php echo JText::_('COM_LOCATION_COLUMN_HEADER_TITLE'); ?>
</th>
<th class="nowrap hidden-phone">
<?php echo JText::_('COM_LOCATION_COLUMN_HEADER_INTROTEXT'); ?>
</th>
<th class="nowrap hidden-phone">
<?php echo JText::_('COM_LOCATION_COLUMN_HEADER_PHOTO'); ?>
</th>
</tr>
</thead>
<tbody>
<?php foreach ($this->locations as $i=>$location) :?>
<tr class="row<?php echo $i % 2; ?>">
<td class="nowrap center hidden-phone">
<?php echo JHtml::_('grid.id', $i, $location->id); ?>
</td>
<td class="has-context">
<a href="<?php echo JRoute::_('index.php?option=com_location&task=
location.edit&id='. (int) $location->id); ?>">
<?php echo $this->escape($location->title); ?>
</a>
</td>
<td class="small">
<?php echo $this->escape($location->introtext); ?>
</td>
<td class="nowrap">
<a href="<?php echo JRoute::_('index.php?option=com_location&task=
location.edit&id='. (int) $location->id); ?>">
<?php echo '<img src="/' . $this->escape($location->photo) .
'" style="height:20px;" />'; ?>
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<input type="hidden" name="task" value="" />
<input type="hidden" name="boxchecked" value="0" />
<?php echo JHtml::_('form.token'); ?>
</div>
</form>
Die Listendarstellung der Urlaubsziele erzeugt eine große, in ein HTML-Formular gewickelte Tabelle. In ihrem <tbody>-Block werden nacheinander alle Locations durchiteriert, die die Businesslogik in der Variablen $locations bereitstellt (foreach ($this->locations as $i->$location)).
Innerhalb der Schleife enthält $location (Singular) alle Daten des aktuell durchlaufenden Urlaubsziels, also ID, Titel, Beschreibung und Fotolink. Die Ausgabe erfolgt über einen einfachen echo-Befehl in der jeweiligen Tabellenzelle, z. B. echo $this-> escape($location->introtext); für die Urlaubszielbeschreibung.
Nach der Schleife erhält das Formular einige versteckte, automatisch befüllte Felder. Besonders wichtig ist das form.token, eine eindeutige Formularkennung, die sogenannte Cross-Site-Request-Forgery-Angriffe, Übergriffe aus einer anderen Joomla!-Installation, vereitelt.
Das Formular enthält außerdem Joomla!-spezifische Framework-Befehle: Per JText-Anweisungen erfolgt die Ausgabe der aus den Sprachdateien stammenden Beschriftungen, z. B. für die Spaltenüberschriften, innerhalb von <th>-Tags. Bemerkenswert sind die JRoute-Anweisungen, über die Sie Joomla!-interne Links erzeugen. Im action-Attribut verweist das Formular damit wieder auf sich selbst; beim anklickbaren Urlaubszieltitel und dem Foto wird ein neuer Link zur Detailseite der Location zusammengebaut:
'index.php?option=com_location&task=location.edit&id='. (int) $location->id
Damit sind die programmatischen Aspekte der Version 0.1.0 der Urlaubszielkomponente fertiggestellt. Die folgenden Abschnitte runden das Paket mit Sprachdateien und der Einrichtung ab, falls Sie nicht das Download-Paket installiert, sondern alle Listings selbst eingegeben haben.
29.1.7 Sprachdateien – »/language/en-GB/en-GB.com_location.(sys.)ini«
Während des Anlegens der Komponenten-Programmdateien wurde vermieden, Beschriftungen im Quelltext hardzucoden. Stattdessen verwendet die Komponente an den Textstellen Sprachschlüssel, ein leistungsfähiges Platzhaltersystem, über das zur Laufzeit Begriffe in der Sprache des Benutzers angezogen werden, vorausgesetzt, eine entsprechende Übersetzung liegt vor.
Standardmäßig sollten alle Erweiterungen immer englischsprachige Texte enthalten, um bei einer Veröffentlichung zu gewährleisten, dass Entwickler und Webmaster rund um den Globus mit der Erweiterung arbeiten können. Diese Sprachdateien befinden sich an zwei verschiedenen Verzeichnispfaden, je nachdem, ob die Komponente bereits in Joomla! installiert ist oder sich in Vorbereitung, der Paketierung, befindet, um später über den Erweiterungsmanager eingerichtet zu werden:
-
Sprachdateien im laufenden Joomla!-System
Alle Sprachdateien für alle Erweiterungen des Administrations-Backends liegen unter /administrator/language/ und darin jeweils auf Sprachunterordner verteilt, z. B. /administrator/language/en-GB/ oder /administrator/language/de-DE/.Sprachdateien für das Frontend folgen demselben Muster, allerdings ohne den Anfangsordner /administrator/.
-
Sprachdateien im Erweiterungspaket
Im Erweiterungspaket befinden sich in oberster Verzeichnisebene die Verzeichnisse /site/ und /admin/, anhand der die Unterscheidung zwischen Dateien für Front- bzw. Backend stattfindet. Darunter folgt jeweils ein Verzeichnis /language/, gefolgt vom Sprachunterverzeichnis /en-GB/ oder /de-DE/.
Pro Erweiterung stellen Sie entweder zwei oder drei Sprachdateien bereit, abhängig davon, ob Sie Begriffsplatzhalter für das Backend und/oder Frontend einsetzen, denn für das Backend sind zwei Sprachdateien erforderlich.
-
en-GB.internerErweiterungsname.sys.ini: Enthält Begriffe für den Installationsvorgang der Erweiterung. Außerdem ziehen sich einige Backend-Manager und das Popup-Fenster der Menüeintragstyp-Auswahl den Komponentennamen und andere Beschriftungen aus dieser Datei.
-
en-GB.internerErweiterungsname.ini: Für Begriffe während der Laufzeit der Erweiterung, hier steckt also der Großteil aller Texte.
Der Aufbau einer Sprachdatei ist über Schlüssel/Wert-Paare recht simpel, z. B. anhand der Datei en-GB.com_location.sys.ini:
COM_LOCATION="Location Manager"
COM_LOCATION_XML_DESCRIPTION="Reiseforum Location Manager"
COM_LOCATION_MENU="Location Manager"
Auf der linken Seite steht der Sprachschlüssel, der stets mit der Art der Erweiterung und dem internen Erweiterungsnamen beginnt, z. B. com_location für die Urlaubszielkomponente. Es folgen durch Unterstriche getrennte, großgeschriebene Kennzeichner für die Stelle, an der der Schlüssel eingesetzt wird. _XML-DESCRIPTION deutet z. B. auf die Komponentenbeschreibung im XML-Manifest, _MENU ist der Name des Menüeintrags im Komponenten-Menü. Letztendlich haben Sie bei der exakten Formulierung des Schlüssels freie Hand, achten Sie aber auf den Komponententyp und -namen, damit sich Ihre Begriffe nicht mit denen anderer Erweiterungen verheddern.
Mit einem Gleichheitszeichen vom Schlüssel getrennt, befindet sich auf der rechten Seite der eigentliche Begriff in Anführungszeichen. Da grundsätzlich alle Joomla!-Dateien in UTF-8 zu speichern sind, brauchen Sie nicht vor der Nutzung von Umlauten und Sonderzeichen zurückzuschrecken.
Weitere Sprachschlüsselbeispiele finden Sie in der Datei en-GB.com_location.ini, die die Begriffe enthält, die die Komponente nach Aktivierung über das Menü Komponenten einsetzt.
COM_LOCATION_MENU="Location Manager"
COM_LOCATION_MANAGER_LOCATIONS="Reiseforum Location Manager"
COM_LOCATION_MANAGER_LOCATION="Reiseforum Location Manager - Edit Location Details"
COM_LOCATION_NEW_LOCATION="Enter new Location"
COM_LOCATION_EDIT_LOCATION="Edit existing Location"
COM_LOCATION_DELETE_CONFIRMATION="Are you sure to delete this Location?"
COM_LOCATION_N_ITEMS_DELETED="Delete successful."
COM_LOCATION_COLUMN_HEADER_TITLE="Location"
COM_LOCATION_COLUMN_HEADER_INTROTEXT="Introtext"
COM_LOCATION_COLUMN_HEADER_PHOTO="Photo"
Anhand der Hauptsprachdatei erkennen Sie, dass es sich empfiehlt, die Sprachschlüssel nach Angabe des Erweiterungsnamens zu gruppieren, z. B. anhand der Spaltenüberschriften in der Listenansicht (_COLUMN_). Noch mehr Übersicht erhalten Sie durch die Verteilung von Kommentaren; Kommentarzeilen beginnen mit einem Semikolon (;).
29.1.8 Testlauf durchführen
Haben Sie die Locations-Komponente nicht über das Download-Paket installiert, sondern bis hierher selbst angelegt, wird es Zeit, die Erweiterung in Joomla! zu registrieren und zu testen. Da alle Dateien bereits an der richtigen Stelle liegen (/administrator/components/com_location/), genügt es, die Erkennungsfunktion zu aktivieren, über Erweiterungen • Verwalten • Seitenleiste Überprüfen • Button Überprüfen • Häkchenmarkierung der entdeckten Komponente • Button Installieren. Nach wenigen Sekunden steht die Location-Komponente im Menü Komponenten zum Aufruf bereit (siehe Abbildung 29.8).
Klicken Sie auf den Menüeintrag, wechselt das Backend zur neuen Komponente, die sich unter der Menüleiste ordnungsgemäß als Reiseforum Location Manager ausweist und die Buttons Neu, Bearbeiten und Löschen sowie eine (noch leere) Listenansicht präsentiert. Im nächsten Schritt bringen Sie etwas Leben in diese Liste, denn nun folgt die Implementierung der Detailansicht, über die neue Elemente angelegt und vorhandene bearbeitet werden.
Debugging-Hinweis: Ist die Komponente einmal installiert, sind Fehlermeldungen, die vielleicht auf Tippfehler zurückzuführen sind, in der Regel beschreibend (siehe Abbildung 29.9). Stellen Sie lediglich sicher, dass Sie die Fehlerkonfiguration unter System • Konfiguration • Reiter Server • Fehler berichten nicht auf Keine gestellt haben. Lokalisieren Sie dann im Fehlerfall die zitierte Datei, und vergleichen Sie noch mal den Code in der benannten Zeile mit den hier gedruckten Listings. Im Zweifelsfall laden Sie das Komponentenpaket von https://joomla-handbuch.com/downloads/handbuch herunter und vergleichen die Dateien mit einem Tool wie z. B. BeyondCompare (http://www.scootersoftware.com).