Custom Elements

This tutorial will walk you through the process of creating a custom element for a type in your ZOO app.


Getting Started

To get an impression of how elements work in general, have a look at the media/zoo/elements/ folder. All of our elements are located there. Each element has its own folder and in each folder you'll find at least two files. The ELEMENT.php and the ELEMENT.xml.

In the xml file you'll find the elements description and the elements parameters. The actual workflow is located in the corresponding php file.


Getting Into Detail

As with almost anything in ZOO, custom modifications should be done in the Applications folder only. Therefore, if it is not already there, we need to create an elements folder media/zoo/applications/APPLICATION/elements.

Next we need to create the actual element folder. Let's call our element Address. We will therefore create a folder like this: media/zoo/applications/APPLICATION/elements/address/.

Note It is also possible to add custom elements to the template of your app: media/zoo/applications/APPLICATION/templates/TEMPLATE/elements/.

The xml File

Now, we need to create the media/zoo/applications/APPLICATION/elements/address/address.xml file.

<?xml version="1.0" encoding="utf-8"?>
<element type="address" group="MY_GROUP">
    <name>Address</name>
    <author>John Doe</author>
    <creationDate>April 2010</creationDate>
    <copyright>THIS CAN PROBABLY BE OMITTED</copyright>
    <authorEmail>john @ doe.com</authorEmail>
    <authorUrl>http://www.johndoe.com</authorUrl>
    <version>1.0.0</version>
    <description>HTML address fields</description>
    <params>
    </params>
    <params group="render">
    </params>
</element>

After the xml declaration, the element metadata part starts. The element will have a name, author, creation date, etc. All of that is pretty self-explanatory. Important are the attributes of the element tag. Type needs to be the same as the element class in the php file and group will be used to group the elements in the edit elements screen.

After the elements metadata the parameters are set. There are two kinds of parameters. The first are the element configuration parameters.

The second params tag has the attribute group with the value render. Here you can choose display options.

In general you can include any Joomla parameters, like text, textarea, list, etc.

The php File

To give the element an actual workflow, we will create this file: media/zoo/applications/APPLICATION/elements/address/address.php.

We will need to create a class, that subclasses the Element class:

class ElementAddress extends Element {
    public function edit() {
    }
}

Notice that the name of the class needs to consist of Element and the element type. Additionally, the class needs to overwrite the base classes abstract edit() function.

Actually this is it. You are good to go. Okay, this element wouldn't be of much use to anyone. We'll at least need to provide some editing and some rendering functionality.

For simplicity our address element will have three text fields: Street, ZIP code and Country.

Let's give the user the possibility to input those values, by altering the edit function.

public function edit() {
    $html = array();
    $html[] = $this->app->html->_('control.editrow', JText::_('Street'),    $this->app->html->_('control.text', $this->getControlName('street'), $this->get('street'), 'size="60" maxlength="255"'));
    $html[] = $this->app->html->_('control.editrow', JText::_('ZIP'), $this->app->html->_('control.text', $this->getControlName('zip'), $this->get('zip'), 'size="60" maxlength="255"'));
    $html[] = $this->app->html->_('control.editrow', JText::_('Country'), $this->app->html->_('control.text', $this->getControlName('country'), $this->get('country'), 'size="60" maxlength="255"'));

    return implode("\n", $html);
}

The edit function will output the three text fields in the item edit. It uses the element.editrow function to generate an edit row, with a label and a textfield. And it uses the control.text function to output this textfield.

To get the current data value, we use the elements get method: $this->get(DATA_KEY);.

For an item to be actually rendered, we will have to overwrite the base classes render function.

public function render($params = array()) {
    return $this->get('street') . ', ' . $this->get('zip') . ', ' .$this->get('country');
}

The $params parameter contains an array with the display options, we specified in the elements xml file.

This will output the three elements values separated by commas. Notice we use the same method of retrieving the element's data, as in the above edit function.

Leaving the function as is wouldn't output any data in the frontend though. We need to overwrite the hasValue function, to tell the renderer, if the element has a value or not.

public function hasValue($params = array()) {
    $street = $this->get('street');
    $zip = $this->get('zip');
    $country = $this->get('country');
    return !empty($street) ||!empty($zip) ||($country);
}

If any of the three values is nonempty, the element is considered to have a value, and therefore will be rendered.

That's it, we have constructed a very simple custom element.


Conclusion

Please have in mind that this tutorial is only an example of how to write the code. You would probably build the address fields by adding text elements to the type, but it demonstrates the element handling quite nicely.

The best way to go about creating your custom elements, is to have a look at the existing elements and learn from them.

ZOO Documentation