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.
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 |
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>
[…]
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).
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
{
}
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«
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;
}
}
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«
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);
}
}
Hier genügt es, der Elternklasse den Tabellennamen (#__location) und den Primärschlüssel (id) mitzuteilen.
Formulardefinition – »/models/forms/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>
Ä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«
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);
}
}
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«
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>
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"
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.
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).