ZOO - CCK Komponente für Joomla!

Geschrieben von Tom   
Samstag, 4. April 2009
Beitragsinhalt
ZOO - CCK Komponente für Joomla!
ZOO Konzept
ZOO Struktur und Events
ZOO Templates und Overrides
ZOO Elemente
ZOO als CCK
ZOO für Entwickler
ZOO Fazit und Kommentare

ZOO für Entwickler

Wer 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.
Als erstes erstellen wir also die XML-Datei, welche nötig ist, um das neue Element bei der Erstellung eines Artikeltyps in der rechten Spalte verfügbar zu machen.

<?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() {    &amp;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. 
Die Edit-Funktion kümmert sich darum eine User-Liste auszugeben. Diese wird genutzt, um den Artikel einem User zuzuordnen. Natürlich könnte man einen Artikel auch fest an den Autoren des Artikel binden, aber manchmal sind Autor und Erfasser nicht diesselbe Person. Das Feld Link Website ist eine kleine Demonstration der mit ZOO möglichen Feld-Parameter.

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.
Über den Parameter Link Website soll also je Artikel festgelegt werden, ob die Website des Autors verlinkt werden soll oder nicht.
Die Render-Funktion holt sich über die Unterfunktion getValue() die relevanten Werte, also alle Informationen des Users aus der Kontakt-Tabelle. Weiterhin wird einfach ein fester Pfad für die Kontaktbilder und den Parameter websitelink festgelegt. Diese Daten werden gemeinsam mit dem Element-Layout an die Funktion renderLayout des Element-Objekts übergeben.

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.
Um unser Element dort zu sehen, müssen wir es in dieses Template einfügen. Besser wäre es jedoch, es nicht in das ZOO-Template direkt einzufügen, sondern ein Override dafür zu erstellen. Nehmen wir an, wir wollen dieses Element nur in der Artikelansicht sehen und nicht in einer Kategorie/Katalogansicht. Wir erstellen also ein Artikel-Override im Verzeichnis /templates/IHRTEMPLATE/html/com_zoo/item. Am besten kopieren wir die Datei item.php aus dem ZOO Templates Verzeichnis /components/com_zoo/templates/blog_classic/ dorthin. Damit diese Datei als Override erkannt wird, muss sie allerdings den Namen des zu überschreibenden Templates haben. Wir benennen also item.php in blog_classic.php um.
Nun können wir innerhalb des Overrides etwas verändern, ohne das ursprüngliche Template zu gefährden. Ich habe einfach in Zeile 79 folgendes eingefügt:

<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.
Wie man bei dem mitgeliefertem Galerie-Element sehen kann, sind dadurch komplexere Anwendungen möglich. In Anbetracht dessen wundert es mich, dass bei ZOO kein Installer integriert wurde, um Elemente von Drittherstellern problemlos installieren zu können. Das ist aufgrund der bei Joomla! vorhandenen Installations Bibliotheken leicht umzusetzen (wir haben das bei bContent innerhalb zweier Tage eingebaut) und macht das integrieren fremder Elemente auch für nicht so kenntnisreiche Nutzer möglich.

Wer selbst mit dem "Contact Details" Element-Typ spielen will, kann diesen im Downloadbereich herunterladen.



 

B01 realisiert zeitgenössische Online-Kommunikationsmittel.
Wir sind spezialisiert auf OSCMS und unterstützen unsere Kunden vom Konzept bis zum Launch mit Erfahrung und exklusiven Komponenten zur Umsetzung von Communitys, Shops, Portalen und Webseiten.

B01 Kunden

Unsere Ideen, unsere Produkte, unsere Kunden.

B01 empfiehlt:

ZOO Content Construktion Kit

ZOO CCK

Virtuemart Shopsystem

E-Commerce

Joomla SEO

SEO

Joomla Content Editor

Content Editor

Joomla Social Networking

JomSocial