ZOO - CCK Komponente für Joomla! |
Geschrieben von Tom | ||||||||||
Samstag, 4. April 2009 | ||||||||||
Seite 7 von 8
ZOO für EntwicklerWer den Artikel bis hierhin gelesen hat, wird festgestellt haben, das es viele spannende Möglichkeiten gibt, besonders im Bereich der Overrides, ZOO in der Darstellung von Inhalten zu beeinflussen. Noch interessanter ist allerdings die Möglichkeit, eigene Element-Typen zu integrieren. Hierfür stellt ZOO ein kleines aber feines Framework zur Verfügung. Um das auszuprobieren, habe ich testweise einen eigenen Elementtyp erstellt. Dieser soll an einem Artikel Informationen zum Autor des Artikels auflisten. Vielleicht ein Bild von ihm, seine E-Mail-Adresse und seine Website. Wenn man solche Informationen zum Autor haben möchte, bieten sich bei Joomla! verschiedene Möglichkeiten. Da gäbe es die standard User-Tabelle, welche allerdings nur rudimentäre Informationen bietet. Eine Website und ein Profilbild gibt es da nicht. Mehr lässt sich mit Komponenten erreichen, welche diese Tabelle erweitern, z. B. JomSocial oder der Community Builder. Dies ginge aber für ein simplen Test etwas weit. Deswegen nutze ich die bei Joomla! integrierte Kontakt Komponente. Hier kann man eine ganze Menge zusätzlicher Informationen einem vorhandenem Joomla! User zuordnen. Damit das ZOO-Element Sinn macht, muss also mindestens ein Kontakt vorhanden sein, welcher die Infos eines Users erweitert. Wir nehmen mal den Admin. In diesem Beispiel werden nur die Felder E-Mail, Webseite und das Kontakt Bild für das ZOO Element genutzt. Ist der Admin-User in der Kontakt Komponente angelegt, kann das neue ZOO Element darauf zugreifen. Ich werde kein Tutorial zum Erstellen von ZOO-Elementen schreiben, sondern kurz darstellen, was die wesentlichen Schritte auf dem Weg dorthin sind. Auf der ZOO Seite ist ein kleines Beispiel eines "hello world" Elements aufgeführt, in dem man sehen kann, was nötig ist, um ein neues Element zu erstellen.
Unser Element wird "Contact Details" heißen und unter dem Schlüsselwort contactdetails verfügbar sein. <?xml version="1.0" encoding="utf-8"?> <element type="contactdetails" group="Contact"> <name>Contact Details</name> <author>Tom Bohacek</author> <creationDate>March 2009</creationDate> <copyright>Copyright (C) 2009 B01</copyright> <authorEmail> Diese E-Mail Adresse ist gegen Spam Bots geschützt, Sie müssen Javascript aktivieren, damit Sie es sehen können </authorEmail> <authorUrl>http://www.bohacek.de<authorUrl> <version>0.1.0</version> <description>Contact Details</description> <params> <param name="name" type="configeditname" default="" label="Name" description="Unique name" /> <param name="label" type="text" default="" label="Label" description="Label used in item editor" /> <param name="description" type="text" default="" label="Description" description="Description tooltip used in item editor" /> <param name="display" type="list" default="3" label="Display" description="Display element only on selected view"> <option value="1">On item view</option> <option value="2">On category view</option> <option value="3">On item/category view</option> <option value="0">Hide</option> </param> </params> </element>
Das ist soweit trivial. Im Element-Tag nutzen wir das Attribut group, um eine eigene ZOO Elementgruppe Contact zu definieren. Im administrator/components/com_zoo/elements/ Verzeichnis erstellen wir ein Verzeichnis für unser Element namens contactdetails. Hier platzieren wir die XML-Datei unter dem Namen contactdetails.xml.
Was wir jetzt brauchen, ist die eigentliche Logik, um das neue Element
im Backend funktionsfähig zu machen. Dazu erstellen wir die Datei
contactdetails.php. Dies wird eine PHP-Klasse, die verschiedene
Funktionen erhält. Im Wesentlichen sind das die zwei Funktionen edit
und render. Die Funktion edit kümmert sich darum, bei der
Bearbeitung eines Artikels im Backend die nötigen Eingaben zu
ermöglichen. Die Funktion render dient dazu, den Inhalt des Elements
für das Frontend verfügbar zu machen. Wer das Joomla!-Framework ein
wenig kennt, sollte mit den folgenden Zeilen keine Schwierigkeiten
haben. <?php // no direct access defined('_JEXEC') or die('Restricted access'); // register parent class JLoader::register('ElementSimpleParams', ZOO_ADMIN_PATH.'/elements/simpleparams/simpleparams.php'); JTable::addIncludePath(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_contact'.DS.'tables'); class ElementContactDetails extends ElementSimpleParams { function ElementContactDetails() { // call parent constructor parent::ElementSimpleParams(); // init vars $this->type = 'contactdetails'; $this->display = 3; } function getValue() { &nbsp; // init vars $params =& $this->getParams(); $row =& JTable::getInstance('contact', 'Table'); $row->load( $this->value ); $row->imgpath = JURI::root().'images/stories/'; $row->websitelink = $params->get('websitelink', 0); return $row; } function render($view = ZOO_VIEW_ITEM) { $value = $this->getValue(); if ($layout = $this->getLayout()) { return Element::renderLayout($layout, array('contact' => $value)); } return null; } function edit() { $params =& $this->getParams(); $websitelink = $params->get('websitelink', 0); $db =& JFactory::getDBO(); $query = 'SELECT c.id AS value, u.name AS text' . ' FROM #__users u ' . ' LEFT JOIN #__contact_details c ON c.user_id = u.id' . ' WHERE u.block = 0' . ' ORDER BY u.name' ; $db->setQuery( $query ); $users[] = JHTML::_('select.option', '0', '- '. JText::_( 'No User' ) .' -' ); $users = array_merge( $users, $db->loadObjectList() ); $html = '<table id="element-'.$this->name.'">'; $html .= JHTML::_('element.editrow', JText::_('User'), JHTML::_('select.genericlist', $users, $this->name.'_value', 'class="inputbox" size="1" ', 'value', 'text', $this->value )); $html .= JHTML::_('element.editrow', JText::_('Link Website'), JHTML::_('select.booleanlist', $this->name.'_params[websitelink]', '', $websitelink )); $html .= '</table>'; return $html; } }
Die Klasse ElementContactDetails erweitert die Klasse
ElementSimpleParams und nicht wie gedacht ElementSimple. Das liegt
daran, dass uns die Klasse ElementSimpleParams ein paar nützliche
Funktionen wie z. B. getParams() bietet.
Wie Sie sehen, hat dieses Feld den Namen contact_params[websitelink].
Wir können also beliebige Parameter definieren, für welche ZOO je
Element eine eigene Tabellenspalte in der Datenbank anlegt. Gespeichert
wird der Wert darin dann so, wie man es auch von Joomla!
Artikelparametern kennt. Das Element-Layout? Genau! Im Frontend existiert das Verzeichnis components\com_zoo\views\element\tmpl\, welches Templates für die einzelnen Elemente enthält. Irgendwo muss ja klar sein, wie so ein Element ausgegeben werden soll. Hier kann also das XHTML des Elements festgelegt werden, ähnlich einem Joomla!-Template. Falls Sie das Kapitel "Templates und Overrides von ZOO" gelesen haben, wird Ihnen klar, das dies das Basis-Template des Elements ist und Sie, wie dort beschrieben, Element-Overrides dafür erstellen können, falls sie eine andere XHTML-Struktur benötigen.
Hier nun das Template für das Element "Contact Details" <?php // no direct access defined('_JEXEC') or die('Restricted access'); ?> <div class="contact-details"> <?php if ($contact->image) : ?> <img class="contact-image" src="<?php echo $contact->imgpath.$contact->image; ?>" title="<?php echo $contact->name ?>" alt="<?php echo $contact->name ?>" /> <?php endif; ?> <?php if ($contact->name ) : ?> <div class="contact-name"><?php echo $contact->name; ?></div> <?php endif; ?> <?php if ($contact->email_to ) : ?> <div class="contact-email"><?php echo $contact->email_to; ?></div> <?php endif; ?> <?php if ($contact->webpage ) : ?> <div class="contact-webpage"> <?php echo $contact->websitelink ? '<a href="' . $contact->webpage . '">' . $contact->webpage . '</a>' : $contact->webpage; ?> </div> <?php endif; ?> </div>
Beim renderLayout Aufruf haben wir die Parameter $layout, und array('contact' => $value) übergeben. Im Template können wir nun direkt auf das Objekt contact zugreifen, um an alle Werte zu gelangen. Da in der getValue() Funktion die Kontakttabelle über das Joomla!-Framework geladen wird, können wir im Prinzip auf alle Felder dieser Tabelle zugreifen. Ich habe mich in diesem Template aber aus Demonstrationszwecken auf die oben Genannten beschränkt. Das Template selbst ist von trivialer Natur. Damit wäre das Element "Contact Details" auch schon fertig. Wenn wir es einem bestimmten Artikeltypen zuordnen, sagen wir Blog Classic, können wir in Artikeln dieses Typs unter dem Feld Contact einen User auswählen und über ein Radiobutton festlegen, ob seine Website verlinkt wird oder nicht. Wenn wir nun im Frontend einen Artikel des Typs Blog Classic aufrufen, sehen wir...nichts neues! Von dem neuen Element ist weit und breit nichts zu sehen. Woran liegt das?
Woher soll das Blog Classic-Template wissen, dass es ein neues
Element darstellen soll? Das Template beinhaltet nur die Darstellung
der bei ZOO mitgelieferten Elemente des Typs Blog Classic. Von unserem neuen Element hat es keine Ahnung. <div style="float:right;"> <?php echo $elements['contact']->render(ZOO_VIEW_ITEM); ?> </div>
Wie gesagt, es soll nur Demonstrationszwecken dienen. Mit dem Aufruf der Render-Funktion des Elements wird das von uns im Element-Template festgelegte XHTML ausgegeben.
Nun, das war ein kurzer Ausflug in die Erstellung eigener Element-Typen
bei ZOO. Dabei habe ich nur an der Oberfläche gekratzt. ZOO nutzt das
MVC-Prinzip vorbildlich und ermöglicht dadurch sehr viel Flexibilität
bei der Entwicklung.
Wer selbst mit dem "Contact Details" Element-Typ spielen will, kann diesen im Downloadbereich herunterladen.
|