Improving components with Joomla! 1.5

0
83
16 min read

(Read more interesting articles on Nhibernate 2 Beginner’s Guide here.)

Improving components

We are going to be working almost exclusively on the backend component in this article but most of what we will be covering could easily be adapted for the frontend component if we wished to do so.

Component backend

When we build the backend of a component there are some very important things to consider. Most components will include at least two backend views or forms; one will display a list of items and another will provide a form for creating or editing a single item. There may be additional views depending on the component but for now we will work with our com_boxoffice component, which consists of two views.

Toolbars

Although we have already built our component toolbars, we didn’t spend much time discussing all the features and capabilities that are available to us, so let’s start with a bit of a review and then add a few enhancements to our component.

Our backend component has two toolbars. The frst is displayed when we access our component from the Components | Box Offce Revues menu:

The second toolbar is displayed when we click on the New or Edit button, or click on a movie title link in the list that is displayed:

Administration toolbars consist of a title and a set of buttons that provide built-in functionality; it requires only a minimum amount of effort to add signifcant functionality to our administration page.

We add buttons to our toolbar in our view classes using the static JToolBarHelper class. In our administration/components/com_boxoffice/views folder we have two views, revues, and revue. In the revues/view.html.php file we generated the toolbar with the following code:

JToolBarHelper::title( JText::_( 'Box Office Revues' ),
'generic.png' );
JToolBarHelper::deleteList();
JToolBarHelper::editListX();
JToolBarHelper::addNewX();
JToolBarHelper::preferences( 'com_boxoffice', '200' );
JToolBarHelper::help( 'help', true );

In our example we set the title of our menu bar to Box Offce Revues, passing it through JText::_(), which will translate it if we have installed a language file. Next we add Delete, Edit, New, Preferences, and Help buttons.

Note that whenever we use JToolBarHelper we must set the title before we add any buttons.

There are many different buttons that we can add to the menu bar; if we cannot find a suitable button we can define our own. Most of the buttons behave as form buttons for the form adminForm, which we will discuss shortly. Some buttons require certain input fields to be included with the adminForm in order to function correctly. The following table lists the available buttons that we can add to the menu bar.

Method Name

Description

addNew

Adds an add new button to the menu bar.>

addNewX

Adds an extended version of the add new button calling hideMainMenu() before submitbutton().

apply

Adds an apply button to the menu bar.

archiveList

Adds an archive button to the menu bar.

assign

Adds an assign button to the menu bar.

back

Adds a back button to the menu bar.

cancel

Adds a cancel button to the menu bar.

custom

Adds a custom button to the menu bar.

customX

Adds an extended version of the custom button calling hideMainMenu() before submitbutton().

deleteList

Adds a delete button to the menu bar.

deleteListX

Adds an extended version of the delete button calling hideMainMenu() before submitbutton().

Divider

Adds a divider, a vertical line to the menu bar.

editCss

Adds an edit CSS button to the menu bar.

editCssX

Adds an extended version of the edit CSS button calling hideMainMenu() before submitbutton().

editHtml

Adds an edit HTML button to the menu bar.

editHtmlX

Adds an extended version of the edit HTML button calling hideMainMenu() before submitbutton().

editList

Adds an edit button to the menu bar.

editListX

Adds an extended version of the edit button calling hideMainMenu() before submitbutton().

help

Adds an Help button to the menu bar.

makeDefault

Adds an Default button to the menu bar.

media_manager

Adds an Media Manager button to the menu bar.

preferences

Adds a Preferences button to the menu bar.

preview

Adds a Preview button to the menu bar.

publish

Adds a Publish button to the menu bar.

publishList

Adds a Publish button to the menu bar.

save

Adds a Save button to the menu bar.

Spacer

Adds a sizable spacer to the menu bar.

title

Sets the Title and the icon class of the menu bar.

trash

Adds a Trash button to the menu bar.

unarchiveList

Adds an Unarchive button to the menu bar.

unpublish

Adds an Unpublish button to the menu bar.

unpublishList

Adds an Unpublish button to the menu bar.

Submenu

Directly below the main menu bar is an area reserved for the submenu. There are two methods available to populate the submenu. The submenu is automatically populated with items defined in the component XML manifest file. We can also modify the submenu, adding or removing menu items using the JSubMenuHelper class. We will begin by adding a submenu using the component XML manifest file. When we last updated our component XML manifest file we placed a menu item in the Administration section:

<menu>Box Office Revues</menu>

This placed a menu item under the Components menu. Our component utilizes a single table, #__boxoffice_revues, which stores specific information related to movie revues. One thing that might make our component more useful is to add the ability to categorize movies by genre (for example: action, romance, science fiction, and so on). Joomla!’s built-in #__categories table will make this easy to implement. We will need to make a few changes in several places so let’s get started.

The first change we need to make is to modify our #_box_office_revues table, adding a foreign key field that will point to a record in the #__categories table. We will add one field to our table immediately after the primary key field id:

`catid` int(11) NOT NULL default '0',

If you have installed phpMyAdmin you can easily add this new field without losing any existing data. Be sure to update the install.sql file for future component installs.

Next we will add our submenu items to the component XML manifest file, immediately after the existing menu declaration:

<submenu>
<menu link="option=com_boxoffice">Revues</menu>
<menu link="option=com_categories
&amp;section=com_boxoffice">Categories</menu>

Note that we use &amp; rather than an ampersand (&) character to avoid problems with XML parsing.

Since we modifed our #__boxoffice_revues table we must update our JTable subclass /tables/revue.php to match by adding the following lines immediately after the id field:

/** @var int */
var $catid = 0;

And finally, we need to modify our layout /views/revue/tmpl/default.php to allow us to select a category or genre for our movie (place this immediately after the </tr> tag of the frst table row, the one that contains our movie title):

<tr>
<td width="100" align="right" class="key">
<label for="catid">
<?php echo JText::_('Movie Genre'); ?>:
</label>
</td>
<td>
<?php echo JHTML::_('list.category',
'catid',
'com_boxoffice',
$this->revue->catid );?>
</td>
</tr>

The call to JHTML::_() produces the HTML to display the selection drop-down list of component specifc categories. The static JHTML class is an integral part of the joomla.html library which we will discuss in the next section.

Creating submenu items through the component XML manifest file is not the only method at our disposal; we can modify the submenu using the static JSubMenuHelper class.

Please note however that these methods differ in a number of ways. Submenu items added using the manifest file will appear as submenu items under the Components menu item as well as the submenu area of the menu bar. For example the Components menu will appear as it does in the following screenshot:

The submenu items will appear on the component list page as shown in the following image:

And the submenu items will also appear on the Category Manager page:

If we were to use JSubMenuHelper class the submenu items would only appear on our component submenu bar; they would not appear on Components | Box Offce Revues or on the Category Manager submenu which would eliminate the means of returning to our component menu. For these reasons it is generally better to create submenus that link to other components using the XML manifest file.

There are, however, valid reasons for using JSubMenuHelper to create submenu items. If your component provides additional views of your data adding submenu items using JSubMenuHelper would be the more appropriate method for doing so. This example adds two options to the submenu using JSubMenuHelper:

// get the current task
$task = JRequest::getCmd('task');
if ($task == 'item1' || $task == 'item2')
{
// determine selected task
$selected = ($task == 'item1');
// prepare links
$item1 = 'index.php?option=com_myextension&task=item1';
$item2 = 'index.php?option=com_myextension&task=item2';
// add sub menu items
JSubMenuHelper::addEntry(JText::_('Item 1'), $item1,
$selected);
JSubMenuHelper::addEntry(JText::_('Item 2'), $item2,
$selected);
}

The addEntry() method adds a new item to the submenu. Items are added in order of appearance. The frst parameter is the name, the second is the link location, and the third is true if the item is the current menu item.

The next screenshot depicts the given example, in the component My Extension, when the selected task is Item1:

There is one more thing that we can do with the submenu. We can remove it. This is especially useful with views for which, when a user navigates away without following the correct procedure, an item becomes locked.

If we modify the hidemainmenu request value to 1, the submenu will not be displayed. We normally do this in methods in our controllers; a common method in which this would be done is edit(). This example demonstrates how:

JRequest::setVar('hidemainmenu', 1);

There is one other caveat when doing this; the main menu will be deactivated. This screenshot depicts the main menu across the top of backend:

This screenshot depicts the main menu across the top of backend when hidemainmenu is enabled; you will notice that all of the menu items are grayed out:

The joomla.html library

The joomla.html library provides a comprehensive set of classes for use in rendering XHMTL. An integral part of the library is the static JHTML class. Within this class is the class loader method JHTML::_(), that we will use to generate and render XHTML elements and JavaScript behaviors.

We generate an XHTML element or JavaScript behavior using the following method:

echo JHTML::_('type', 'parameter_1', …,'parameter_N');

The JHTML class supports eight basic XHTML element types; there are eight supporting classes that provide support for more complex XHTML element types and JavaScript behaviors. While we will not be using every available element type or behavior, we will make good use of a signifcant number of them throughout this article; enough for you to make use of others as the need arises.

The basic element types are:

calendar

Generates a calendar control field and a clickable calendar image

date

Returns a formatted date string

iframe

Generates a XHTML <iframe></iframe> element

image

Generates a XHTML <img></img> element

link

Generates a XHTML <a></a> element

script

Generates a XHTML <script></script> element

style

Generates a <link rel=”stylesheet” style=”text/css” /> element

tooltip

Generates a popup tooltip using JavaScript

There are eight supporting classes that provide more complex elements and behaviors that we generally define as grouped types. Grouped types are identifed by a group name and a type name. The supporting classes and group names are:

Class

Group

Description

JHTMLBehavior

behavior

Creates JavaScript client-side behaviors

JHTMLEmail

Email

Provides email address cloaking

JHTMLForm

Form

Generates a hidden token field

JHTMLGrid

Grid

Creates HTML form grids

JHTMLImage

image

Enables a type of image overriding in templates

JHTMLList

list

Generates common selection lists

JHTMLMenu

menu

Generates menus

JHTMLSelect

select

Generates dropdown selection boxes

All group types are invoked using the JHTML::_(‘group.type’,…) syntax.

The following section provides an overview of the available group types.

behavior

These types are special because they deal with JavaScript in order to create client-side behaviors.

We’ll use behavior.modal as an example. This behavior allows us to display an inline modal window that is populated from a specifc URI. A modal window is a window that prevents a user from returning to the originating window until the modal window has been closed. A good example of this is the ‘Pagebreak’ button used in the article manager when editing an article.

The behavior.modal type does not return anything; it prepares the necessary JavaScript. In fact, none of the behavior types return data; they are designed solely to import functionality into the document.

This example demonstrates how we can use the behavior.modal type to open a modal window that uses www.example.org as the source:

// prepare the JavaScript parameters
$params = array('size'=>array('x'=>100, 'y'=>100));
// add the JavaScript
JHTML::_('behavior.modal', 'a.mymodal', $params);
// create the modal window link
echo '<a class="mymodal" title="example"
href="http://www.example.org"
rel="{handler: 'iframe',
size: {x: 400, y: 150}}">Example Modal Window</a>';

The a.mymodal parameter is used to identify the elements that we want to attach the modal window to. In this case, we want to use all <a> tags of class mymodal. This parameter is optional; the default selector is a.modal.

We use $params to specify default settings for modal windows. This list details the keys that we can use in this array to define default values:

  • ajaxOptions
  • size
  • onOpen
  • onClose
  • onUpdate
  • onResize
  • onMove
  • onShow
  • onHide

The link that we create can only be seen as special because of the JavaScript in the rel attribute. This JavaScript array is used to determine the exact behavior of the modal window for this link. We must always specify handler; this is used to determine how to parse the input from the link. In most cases, this will be iframe, but we can also use image, adopt, url, and string.

The size parameter is optional; here it is used to override the default specifed when we used the behavior.modal type to import the JavaScript. The settings have three layers of inheritance:

  • The default settings defined in the modal.js file
  • The settings we define when using the behavior.modal type
  • The settings we define when creating the link

This is a screenshot of the resultant modal window when the link is used :

Here are the behavior types:

calendar

Adds JavaScript to use the showCalendar() function

caption

Places the image title beneath an image

combobox

Adds JavaScript to add combo selection to text fields

formvalidation

Adds the generic JFormValidator JavaScript class to the document

keepalive

Adds JavaScript to maintain a user’s session

modal

Adds JavaScript to implement modal windows

mootools

Adds the MooTools JavaScript library to the document head

switcher

Adds JavaScript to toggle between hidden and displayed elements

tooltip

Adds JavaScript required to enable tooltips

tree

Instantiates the MooTools JavaScript class MooTree

uploader

Adds a dynamic file uploading mechanism using JavaScript

email

There is only one e-mail type.

cloak

Adds JavaScript to encrypt e-mail addresses in the browser

form

There is only one form type.

token

Generates a hidden token field to reduce the risk of CSRF exploits

grid

The grid types are used for displaying a dataset’s item elements in a table of a backend form. There are seven grid types, each of which handles a commonly defined database field such as access, published, ordering, checked_out.

The grid types are used within a form named adminForm that must include a hidden field named boxchecked with a default value of 0 and another named task that will be used to determine which task a controller will execute.

To illustrate how the grid types are used we will use grid.id and grid.published along with our component database table #__boxoffice_revues that has a primary key field named id, a field named published, which we use to determine if an item should be displayed, and a field named name.

We can determine the published state of a record in our table by using grid.published.

This example demonstrates how we might process each record in a view form layout and output data into a grid or table ($this->revues is an array of objects representing records from the table):

<?php
$i = 0;
foreach ($this->revues as $row) :
$checkbox = JHTML::_('grid.id', ++$i, $row->id);
$published = JHTML::_('grid.published', $row, $i); ?>
<tr class=<?php echo "row$i%2"; ?>">
<td><?php echo $checkbox; ?></td>
<td><?php echo $row->name; ?></td>
<td align="center"><?php echo $published ?></td>
</tr>
<?php
endforeach;
?>

If $revues were to contain two objects named Item 1 and Item 2, of which only the frst object is published, the resulting table would look like this:

Not all of the grid types are used for data item elements. The grid.sort and grid.order types are used to render table column headings. The grid.state type is used to display an item state selection box, All, Published, Unpublished and, optionally, Archived and Trashed.

The grid types include:

access

Generates an access group text link

checkedOut

Generates selectable checkbox or small padlock image

id

Generates a selectable checkbox

order

Outputs a clickable image for every orderable column

published

Outputs a clickable image that toggles between published & unpublished

sort

Outputs a sortable heading for a grid/table column

state

Outputs a drop-down selection box called filter_state

image

We use the image types to perform a form of image overriding by determining if a template image is present before using a system default image.

We will use image.site to illustrate, using an image named edit.png:

echo JHTML::_('image.site', 'edit.png');

This will output an image tag for the image named edit.png. The image will be located in the currently selected template’s /images folder. If edit.png is not found in the /images folder then the /images/M_images/edit.png file will be used.

We can change the default directories using the $directory and $param_directory parameters.

There are two image types, image.administrator and image.site.

administrator

Loads image from backend templates image directory or default image

site

Loads image from frontend templates image directory or default image

LEAVE A REPLY

Please enter your comment!
Please enter your name here