29.2 Detailansicht der Backend-Komponente ergänzen 

In Version 0.2.0 füllen Sie die Locations-Komponente mit Inhalten. Dazu erhält die Komponente ein weiteres Formular, das die Detailansicht eines Urlaubsziels, also einer einzelnen Location, einblendet und die Bearbeitung der Textfelder und Bildfelder erlaubt (siehe Abbildung 29.10). Das ist vergleichbar mit der Ansicht eines einzelnen Beitrags, nachdem Sie im Beitragsmanager auf den Titel klickten.
Ziel: Neue Urlaubsziele können angelegt und vorhandene bearbeitet oder gelöscht werden. Die Speicherung der Urlaubsziele erfolgt in der Datenbank von Joomla!.
Vorgehen: Sie ergänzen die Komponente um einen weiteren View für die Detailansicht inklusive zugehörigem Model und View-Controller und ergänzen die notwendigen Referenzen und Sprachschlüssel in XML-Manifest und Sprachdatei.
Abbildung 29.10 In der Detailansicht der Locations-Komponente ist die Bearbeitung einzelner Inhaltselemente vorgesehen.
Zuvor ein Blick auf die Verzeichnis- und Dateistruktur. Veränderte bzw. neue Dateien sind hervorgehoben.
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 |
location.php | View-Controller für die Einzelansicht |
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. |
location.php | Model für die Einzelansicht |
locations.php | Model für die Listenansicht |
/forms/ | Enthält die Komponente begleitende JForm-Formulare. |
location.xml | JForm-XML für das Bearbeitungsformular |
/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 |
/tables/ | Enthält Datenbanktabellenabbildungen für die Models. |
location.php | Tabellenabbildung für die Einzelansicht |
/views/ | Enthält Businesslogik und HTML-Template aller Views. |
/location/ | Enthält den View der Einzelansicht. |
view.html.php | Businesslogik der Einzelansicht |
tmpl/ | Enthält HTML-Templates. |
edit.php | HTML-Template des Bearbeitungsformulars |
/locations/ | Enthält den View der Listenansicht. |
view.html.php | Businesslogik der Listenansicht |
/tmpl/ | Enthält HTML-Templates. |
default.php | HTML-Template der Listenansicht |
Tabelle 29.3 Blick in die Verzeichnisstruktur der Location-Komponente Version 0.2.0 innerhalb des Verzeichnisses »/admin/«
29.2.1 XML-Manifest – »location.xml« 

Für die Detailansicht ist es erforderlich, ein zusätzliches Tabellenobjekt bereitzustellen (dazu gleich mehr, wenn es um das neue Model geht). Es wird in einem neuen Verzeichnis /tables/ angelegt, darum erhält das XML-Manifest eine weitere Zeile, die dieses Verzeichnis referenziert.
[…]
<files folder="admin">
<filename>index.html</filename>
<zeichen typ="programmierelement"> <filename>controller.php</filename>
</zeichen>
<zeichen typ="programmierelement"> <filename>location.php</filename>
</zeichen>
<zeichen typ="programmierelement"> <folder>controllers</folder></zeichen>
<zeichen typ="programmierelement"> <folder>models</folder></zeichen>
<zeichen typ="programmierelement"> <folder>sql</folder></zeichen>
<folder>tables</folder>
<zeichen typ="programmierelement"> <folder>views</folder></zeichen>
</files>
[…]
Listing 29.12 »location.xml«: Version 0.2.0 des Komponenten-XML-Manifests verweist auf Sprachdateien, Datenbankscripts und Verzeichnisse und Dateien der Backend-Komponente.
29.2.2 View-Controller – »location.php« 

Für die Detailansicht entsteht ein neuer View, in dem sich alles um die Darstellung und Bearbeitungsmöglichkeit eines einzelnen Inhaltselements dreht. Zur Steuerung dieses Views ist ein weiterer View-Controller nötig (siehe Abbildung 29.11).
Abbildung 29.11 Version 0.2.0 der Locations-Komponente erhält einen weiteren View für die Detailansicht inklusive zugehörigem Model und Controller.
Detailansicht-Controller – »/controllers/location.php«
Ebenfalls im /controllers/-Unterverzeichnis angesiedelt ist der Controller für die Detailansicht, location.php; beachten Sie den Singular der Schreibweise.
<?php
defined('_JEXEC') or die;
class LocationControllerLocation extends JControllerForm
{
}
Listing 29.13 »/controllers/location.php«: Controller für den View der Einzelausgabe
Auch die Einzelansicht der Locations benötigt einen besonderen Controller. In diesem Fall, damit er seine Aufgaben zur Steuerung des Formulars erfüllen kann, das nach Klick auf den Button Neu oder Bearbeiten erscheint. Ein JControllerLegacy würde hier nicht genügen, der JControllerForm muss her. Seine Basisfunktionen sind für die Location-Komponente aber ausreichend, darum wird in der Controller-Klasse nichts überschrieben oder erweitert.
29.2.3 Model – »location.php« 

Weiter geht es im Model, das für das Lesen und Schreiben der Datensätze der Inhaltselemente sorgt (siehe Abbildung 29.12).
Detailansicht-Model – »/models/location.php«
Abbildung 29.12 Für die Detailansicht liest das Model nicht nur Inhalte aus der Datenbank, sondern schreibt bzw. überschreibt neue oder bestehende Datensätze.
Das Einzelansicht-Model ist komplexer, da es zur Darstellung der einzelnen Location genaue Angaben zum Datensatz und zur Formulardarstellung benötigt. Das Model liegt im gleichen Verzeichnis wie das zur Liste, /administrator/components/com_location/models/, trägt aber den Singularnamen location.php.
<?php
defined('_JEXEC') or die;
class LocationModelLocation extends JModelAdmin
{
public function getTable($type = 'Location', $prefix = 'LocationTable',
$config = array())
{
return JTable::getInstance($type, $prefix, $config);
}
public function getForm($data = array(), $loadData = true)
{
$app = JFactory::getApplication();
$form = $this->loadForm('com_location.location', 'location',
array('control'=>'jform', 'load_data'=>$loadData));
if (($form))
{
return false;
}
return $form;
}
protected function loadFormData()
{
$data = JFactory::getApplication()->getUserState('com_
location.edit.location.data', array());
if (($data))
{
$data = $this->getItem();
}
return $data;
}
}
Listing 29.14 »/models/location.php«: Model zum Abrufen und Beschreiben der Einzelansicht
Der Bezug zur Tabelle in getTable() dient dem Lesen und Schreiben eines einzelnen Datensatzes, achten Sie auf die Singularschreibweise LocationTable. (Die Tabellendefinition folgt gleich in einer separaten Datei.) getForm() und loadFormData() initialisieren und befüllen das Formular.
Tabellendefinition – »/tables/location.php«
Abbildung 29.13 Für den Zugriff auf die Datenbanktabelle der Locations erhält das Model ein begleitendes Tabellenobjekt.
Für die Tabellendefinitionen ist ein separates Unterverzeichnis /administrator/components/com_location/tables/ vorgesehen, das die Einzelansichtsdatei location.php enthält.
<?php
defined('_JEXEC') or die;
class LocationTableLocation extends JTable
{
public function __construct(&$db)
{
parent::__construct('#__location', 'id', $db);
}
}
Listing 29.15 »/tables/location.php«: Tabellendefinition für die Einzelansicht
Hier genügt es, der Elternklasse den Tabellennamen (#__location) und den Primärschlüssel (id) mitzuteilen.
Formulardefinition – »/models/forms/location.xml«
Abbildung 29.14 Die Formulardefinition in »location.xml«
Zum Abschluss folgt die Formulardefinition der bearbeitbaren Detailansicht, eine XML-Datei location.xml im Unterverzeichnis /models/forms/. Bei ihr handelt es sich um ein JForm, Sie dürfen also alle Formularfelder einsetzen, die Sie bereits aus den <config>-Blöcken der Plugin- und Modul-XML-Manifeste kennen.
<?xml version="1.0" encoding="utf-8"?>
<form>
<fieldset>
<field name="id"
type="text"
default="0"
label="JGLOBAL_FIELD_ID_LABEL"
readonly="true"
class="readonly"
description="JGLOBAL_FIELD_ID_DESC" />
<field name="title"
type="text"
class="inputbox"
size="40"
label="JGLOBAL_TITLE"
description="JGLOBAL_FIELD_TITLE_DESC"
required="true" />
<field name="introtext"
type="textarea"
class="inputbox"
cols="40"
rows="10"
label="COM_LOCATION_FIELD_INTROTEXT_LABEL"
description="COM_LOCATION_FIELD_INTROTEXT_DESC" />
<field name="photo"
type="media"
size="40"
directory=""
hide_none="1"
label="COM_LOCATION_FIELD_PHOTO_LABEL"
description="COM_LOCATION_FIELD_PHOTO_DESC" />
</fieldset>
</form>
Listing 29.16 »/models/forms/location.xml«: Im Formular der Einzelansicht verwenden Sie JForm-Formularfelder.
Ähnlich wie im XML-Manifest von Plugins und Modulen listen Sie innerhalb des <fieldset>-Blocks nacheinander alle einzusetzenden Formularfelder. Das type-Attribut markiert, um welche Art Formularfeld es sich handelt – eine Übersicht über die am häufigsten verwendeten finden Sie in Abschnitt 25.3.2, »JForm-Feldtypen«. Beachten Sie die Attribute label und description. Sie enthalten Sprachschlüssel, um die zum Ende dieses Abschnitts die Sprachdatei ergänzt wird – mit Ausnahme der mit JGLOBAL_ beginnenden Schlüssel, die von Joomla! vorgegebene Begriffe einsetzen.
29.2.4 View – »view.html.php« und »edit.php« 

Auch bei der Einzelansicht bzw. -bearbeitung eines Urlaubsziels erfolgt eine Trennung von Businesslogik und HTML-Template. Die Verzeichnisstruktur ist unter /administrator/components/com_location/views/location/ identisch mit der der Listenansicht, enthält also einen Unterordner /tmpl/ zur Aufnahme von einer oder mehreren Templatedateien.
View für die Detailansicht – »/views/location/view.html.php«
Abbildung 29.15 Die Applikationslogik des Detailansicht-Views holt sich Daten des Models und die JForm-Formulardefinition und befüllt das HTML-Template »edit.php«.
Zunächst zur Businesslogik in der Datei views.html.php:
<?php
defined('_JEXEC') or die;
class LocationViewLocation extends JViewLegacy
{
protected $location;
protected $form;
public function display($tpl = null)
{
$this->location = $this->get('Item');
$this->form = $this->get('Form');
JFactory::getApplication()->input->set('hidemainmenu', true);
JToolbarHelper::title(JText::_('COM_LOCATION_MANAGER_LOCATION'), '');
JToolbarHelper::save('location.save');
if (($this->location->id))
{
JToolbarHelper::cancel('location.cancel', 'JTOOLBAR_CANCEL');
}
else
{
JToolbarHelper::cancel('location.cancel', 'JTOOLBAR_CLOSE');
}
parent::display($tpl);
}
}
Listing 29.17 »/views/location/view.html.php«: View-Variante für das einzelne »location«-Formular zur Neuanlage oder Bearbeitung
In dieser view.html.php-Datei erfolgt nicht nur die Bereitstellung der eigentlichen Location mit get('Item'), sondern auch des Bearbeitungsformulars (get('Form')), dessen Eingabefelder in der zuvor abgelegten Datei /models/forms/location.xml definiert sind.
set('hidemainmenu', true) dient der Deaktivierung des oberen Joomla!-Menüs. Damit wird das Formular modal, und der Benutzer verlässt es nicht versehentlich über einen Menüpunkt, sondern kann die Bearbeitung nur über einen der Buttons Speichern & Schliessen oder Schliessen/Abbrechen beenden. Die Buttonleiste, die diese Buttons enthält, entsteht über die darauf folgenden JToolbarHelper-Zeilen.
HTML-Template für die Detailansicht – »/views/location/tmpl/edit.php«
Abbildung 29.16 »edit.php« ist schließlich das HTML-Template, das das Bearbeitungsformular enthält
Last, but not least enthält die Datei /tmpl/edit.php das eigentliche HTML-Formular, ebenfalls gespickt mit PHP-Platzhaltern, um die Feldbeschriftungen und -inhalte dynamisch zur Laufzeit auszugeben.
<?php
defined('_JEXEC') or die;
?>
<form action="<?php echo JRoute::_('index.php?option=com_location&layout=edit&
id=' . (int) $this->location->id); ?>" method="post" name="adminForm"
id="adminForm" class="form-validate">
<div class="row-fluid">
<div class="span10 form-horizontal">
<fieldset>
<?php echo JHtml::_('bootstrap.startTabSet', 'editLocation',
array('active' => 'general')); ?>
<?php echo JHtml::_('bootstrap.addTab', 'editLocation',
'general', ($this->location->id) ? JText::_('COM_LOCATION_
NEW_LOCATION') : JText::sprintf('COM_LOCATION_EDIT_LOCATION',
$this->location->id)); ?>
<div class="control-group">
<div class="control-label"><?php echo $this->form->
getLabel('title'); ?></div>
<div class="controls"><?php echo $this->form->
getInput('title'); ?></div>
</div>
<div class="control-group">
<div class="control-label"><?php echo $this->form->
getLabel('introtext'); ?></div>
<div class="controls"><?php echo $this->form->
getInput('introtext'); ?></div>
</div>
<div class="control-group">
<div class="control-label"><?php echo $this->form->
getLabel('photo'); ?></div>
<div class="controls"><?php echo $this->form->
getInput('photo'); ?></div>
</div>
<?php echo JHtml::_('bootstrap.endTab'); ?>
<input type="hidden" name="task" value="" />
<?php echo JHtml::_('form.token'); ?>
<?php echo JHtml::_('bootstrap.endTabSet'); ?>
</fieldset>
</div>
</div>
</form>
Listing 29.18 »/views/locations/tmpl/edit.php« ist die HTML-Ausgabe des »locations«-Bearbeitungsformulars.
Auch die Einzelansichtsseite besteht aus einem großen HTML-Formular, dessen action auf sich selbst verweist und das am Ende ein form.token zur Vermeidung von Cross-Site-Request-Forgery-Angriffen enthält. Beachten Sie den URL-Parameter &layout=edit in der Formular-action, der den Namen des hier eingesetzten HTML-Templates enthält.
Auffällig ist der Einsatz eines Bootstrap-TabSets. Dabei handelt es sich um die Reiter, die Sie z. B. aus der Beitragsbearbeitung (Inhalt, Veröffentlichung, Bilder und Links etc.) kennen und deren Formularfelder Teile eines großen Gesamtformulars sind, das mit Bootstraps Hilfe auf mehrere Seiten aufgeteilt wird. Jeder Reiter befindet sich dabei innerhalb eines Bootstrap-Tabs:
<?php echo JHtml::_('bootstrap.addTab', 'uebergreifenderNameFuerDieReitergruppe',
'IDdesEinzelnenReiters', 'ReiterBeschriftung')); ?>
<div>Reiterinhalt</div>
<?php echo JHtml::_('bootstrap.endTab'); ?>
Innerhalb der Tabs befinden sich wieder zahlreiche Platzhalter, die die über view.html.php bereitgestellten Formularfeldbeschriftungen und -inhalte in das HTML-Formular injizieren.
Die Programmergänzungen für die Detailansicht sind damit abgeschlossen, nun fehlen nur noch die eigentlichen Formularfeldbeschriftungen, die in der Formulardefinition als Sprachschlüssel hinterlegt wurden.
29.2.5 Sprachdateien vervollständigen – »/language/en-GB/en-GB.com_location.ini« 

Erinnern Sie sich an die Formulardefinition in /models/forms/location.xml? Dort wurden einige zusätzliche Sprachschlüssel für die Formularfeldbeschriftungen eingesetzt. Zwei stammten aus dem umfangreichen Wortschatz von Joomla!, aber die Labels für den Beschreibungstext und das Foto enthalten einen komponentenspezifischen Kennzeichner; ihre Definitionen ergänzen Sie also in der Datei en-GB.com_location.ini wie folgt.
[…]
; Form Fields
COM_LOCATION_FIELD_INTROTEXT_LABEL="Introtext"
COM_LOCATION_FIELD_INTROTEXT_DESC="Enter a text describing the location"
COM_LOCATION_FIELD_PHOTO_LABEL="Photo"
COM_LOCATION_FIELD_PHOTO_DESC="Pick a photo that represents this beautiful location"
COM_LOCATION_COLUMN_HEADER_TITLE="Location"
COM_LOCATION_COLUMN_HEADER_INTROTEXT="Introtext"
COM_LOCATION_COLUMN_HEADER_PHOTO="Photo"
Listing 29.19 »/language/en-GB/en-GB.com_location.ini«: Ergänzungen (hervorgehoben) der Feldbeschriftungen für das Detailansichtsformular
29.2.6 Testlauf durchführen 

Zeit für den nächsten Probelauf. Falls Sie die Ergänzungen direkt in Ihrer Joomla!-Installation vornahmen, wechseln Sie einfach ins Administrations-Backend und rufen die neue Komponente erneut über Komponenten • Location Manager auf. Arbeiten Sie mit den Download-Paketen, suchen Sie auf der Begleitwebsite nach dem ZIP-Archiv für Version 0.2.0, und installieren Sie es.
Abbildung 29.17 Testen Sie das Neuanlegen, Bearbeiten (mit Bilderauswahl) und Löschen von Urlaubszielen.
Abbildung 29.18 Nach der Ergänzung von Urlaubszielen über die Detailansicht erfüllt die Listenansicht auch endlich ihren Zweck und präsentiert eine übersichtliche Liste der Locations.
Ab sofort lassen sich alle Buttons der Listenansicht bedienen (siehe Abbildung 29.18) und Inhaltselemente in der Detailansicht mit sinnvollen Daten befüllen. Probieren Sie nacheinander alle Funktionen durch, angefangen bei der Neuanlage einer Location über den Button Neu über die Bearbeitung eines existierenden Urlaubsziels (Markierung und Button Bearbeiten oder Klick auf den Titel (siehe Abbildung 29.17) bis hin zum Löschen (Häkchenmarkierung und Button Löschen).