16 min read

(Read more interesting articles on Joomla!1.5 here.)

Application message queue

You may have noticed that when we raise a notice or a warning, a bar appears across the top of the page containing the notice or warning message. These messages are part of the application message queue.

The application message queue is a message stack that is displayed the next time the application renders an HTML view. This means that we can queue messages in one request but not show them until a later request.

There are three core message types: message, notice, and error. The next screenshot depicts how each of the different types of application message is rendered:

Easily modifying a page with Joomla 1.5

We use the application enqueueMessage() method to add a message to the queue. This example demonstrates how we would add all of the messages shown in the previous screenshot to the message queue:

$mainframe->enqueueMessage('A message type message');
$mainframe->enqueueMessage('A notice type message', 'notice');
$mainframe->enqueueMessage('An error type message', 'error');

The first parameter is the message that we want to add and the second parameter is the message type; the default is message. It is uncommon to add notice or error messages this way; normally we will use JError::raiseNotice() and JError::raiseWarning() respectively.

This means that we will, in most cases, use one parameter with the enqueueMessage() method. It is possible however, to add messages of our own custom types. This is an example of how we would add a message of type bespoke:

$mainframe->enqueueMessage('A bespoke type message', 'bespoke');

Custom type messages will render in the same format as message type messages. Imagine we want to use the bespoke message type to render messages but not display them. This could be useful for debugging purposes.

This example demonstrates how we can add a CSS Declaration to the document, using the methods described earlier to modify the way in which the bespoke messages are displayed:

$css = '/* Bespoke Error Messages */
#system-message dt.bespoke
{
display: none;
}

dl#system-message dd.bespoke ul
{
color: #30A427;
border-top: 3px solid #94CA8D;
border-bottom: 3px solid #94CA8D;
background: #C8DEC7 url(notice-bespoke.png) 4px 4px no-repeat;
}';

$doc =& JFactory::getDocument();
$doc->addStyleDeclaration($css);

Now when bespoke messages are rendered, they will appear like this:

Easily modifying a page with Joomla 1.5

Redirecting the browser

Redirection allows us to redirect the browser to a new location. Joomla! provides us with some easy ways in which to redirect the browser.

Joomla! redirects are implemented using HTTP 301 redirect response codes. In the event that response headers have already been sent, JavaScript will be used to redirect the browser.

The most common time to redirect a browser is after a form has been submitted. There are a number of reasons why we might want to do this, such as the following:

  • Redirecting after form submission prevents forms from being submitted multiple times when the browser is refreshed
  • We can redirect to different locations depending on the submitted data
  • Redirecting to another view reduces the amount of development required for each task in the controller

There are many scenarios where the use of a redirect is common. The following list identifies some of these:

  • Canceling editing an existing item
  • Copying items
  • Creating new items and updating existing items
  • Deleting items
  • Publishing or unpublishing items
  • Updating item ordering

Imagine a user submits a form that is used to create a new record in a database table. The first thing we need to do when we receive a request of this type is to validate the form contents. This next data flow diagram describes the logic that we could implement:

Easily modifying a page with Joomla 1.5

The No route passes the invalid input to the session. We do this so that when we redirect the user to the input form we can repopulate the form with the invalid input. If we do not do this the user will have to complete the entire form again.

We may choose to omit the Pass invalid input to user session process as the core components do. It is normal to include JavaScript to validate forms before they are submitted, and since the majority of users will have JavaScript support enabled, this may be a good approach to use.

Note that omitting this process is not the same as omitting form validation. We must never depend on JavaScript or other client-side mechanisms for data validation. A good approach is to initially develop forms without client-side validation while ensuring that we properly handle invalid data with server-side scripts.

As a quick aside, a good way to validate form contents is to use a JTable subclass check() method.

If we place failed input into the session, we might want to put it in its own namespace. This makes it easier to remove the data later and helps prevent naming conflicts. The next example demonstrates how we might add the field value of myField to the myForm session namespace:

// get the session
$session =& JFactory::getSession();

// get the raw value of myField
$myFieldValue = JRequest::getString('myField', '', 'POST',
JREQUEST_ALLOWRAW);

// add the value to the session namespace myForm
$session->set('myField', $myFieldValue, 'myForm')

When we come to display the form we can retrieve the data from the session using the get() method. Once we have retrieved the data we must remember to remove the data from the session, otherwise it will be displayed every time we view the form (unless we use another flag as an indicator). We can remove data items from the myForm namespace using the clear() method:

// get the session
$session =& JFactory::getSession();

// Remove the myField
$session->clear('myField', 'myForm');

The final thing we do in the No route is to redirect the user back to the input form. When we do this, we must add some messages to the application queue to explain to the user why the input has been rejected.

The Yes route adds a new record to the database and then redirects the user to the newly created item. As with the No route, it is normal to queue a message that will say that the new item has been successfully saved, or something to that effect.

There are essentially two ways to redirect. The first is to use the application redirect() method.

It is unusual to use this mechanism unless we are developing a component without the use of the Joomla! MVC classes. This example demonstrates how we use the application method:

$mainframe->redirect('index.php?option=com_boxoffice');

This will redirect the user’s browser to index.php?option=com_boxoffice. There are two additional optional parameters that we can provide when using this method. These are used to queue a message.

This example redirects us, as per the previous example, and queues a notice type message that will be displayed after the redirect has successfully completed:

$mainframe->redirect('index.php?option=com_boxoffice',
'Some Message', 'notice');

The final parameter, the message type, defaults to message.

The application redirect() method immediately queues the message, redirects the user’s browser, and ends the application.

The more common mechanism for implementing redirects is to use the JController setRedirect() method. We generally use this from within a controller method that handles a task, but because the method is public we can use it outside of the controller.

This example, assuming we are within a JController subclass method, will set the controller redirect to index.php?option=com_boxoffice:

$this->setRedirect('index.php?option=com_boxoffice');

As with the application redirect() method, there are two additional optional parameters that we can provide when using this method. These are used to queue a message.

This example sets the controller redirect, as per the previous example, and queues a notice type message that will be displayed after the redirect has successfully completed:

$this->setRedirect('index.php?option=com_boxoffice', 'Some Message',
'notice');

Unlike the application redirect() method, this method does not immediately queue the optional message, redirect the user’s browser, and end the application.To do this we must use the JController redirect() method.

It is normal, in components that use redirects, to execute the controller redirect() method after the controller has executed a given task. This is normally done in the root component file, as this example demonstrates:

$controller = new BoxofficeController();
$controller->execute(JRequest::getCmd('task'));
$controller->redirect();

Component XML metadata files and menu parameters

When we create menu items, if a component has a selection of views and layouts, we can choose which view and which layout we want to use. We can create an XML metadata file for each view and layout. In these files we can describe the view or layout and we can define extra parameters for the menu item specific to the specified layout.

Our component frontend has a single view with two layouts: default.php and list.php. The next figure describes the folder structure we would expect to find in the views folder (for simplicity, only the files and folders that we are discussing are included in the figure):

Easily modifying a page with Joomla 1.5

When an administrator creates a link to this view, the options displayed will not give any information beyond the names of the folders and files described above, as the next screenshot demonstrates:

Easily modifying a page with Joomla 1.5

The first element of this list that we will customize is the view name, Revue. To do this we must create a file in the revue folder called metadata.xml. This example customizes the name and description of the revue view:

?xml version="1.0" encoding="utf-8"?>
<metadata>
<view title="Movie Revues">
<message>
<![CDATA[Movie Revues]]>
</message>
</view>
</metadata>

Now if an administrator were to view the list of menu item types, Revue would be replaced with the text Movie Revues as defined in the view tag title attribute. The description, defined in the message tag, is displayed when the mouse cursor is over the view name.

The next task is to customize the definitions of the layouts, default.php and list.php.

Layout XML metadata files are located in the tmpl folder and are named the same as the corresponding layout template file. For example, the XML metadata file for default.php would be named default.xml.

So we need to add the files default.xml and list.xml to the tmpl folder.

Within a layout XML metadata file, there are two main tags in which we are interested: layout and state. Here is an example of a XML metadata file

<?xml version="1.0" encoding="utf-8"?>
<metadata>
<layout title="Individual Revue">
<message>
<![CDATA[Individual movie revue.]]>
</message>
</layout>
<state>
<name>Individual Revue</name>
<description>Individual movie revue.</description>
</state>
</metadata>

And here is the list.xml file:

<?xml version="1.0" encoding="utf-8"?>
<metadata>
<layout title="Revue List">
<message>
<![CDATA[Summary list of revues.]]>
</message>
</layout>
<state>
<name>Revue List</name>
<description>Summary list of revues.</description>
</state>
</metadata>

At first glance it may seem odd that we appear to be duplicating information in the layout and state tags. However, the layout tag includes information that is displayed in the menu item type list (essentially an overview). The state tag includes information that is displayed during the creation of a menu item that uses the layout.

There are occasions when a more detailed description is required when we come to define a menu item. For example, we may want to warn the user that they must fill in a specific menu parameter. We will discuss menu parameters in a moment.

Assuming we created the default.xml and list.xml files as shown previously, our menu item type list would now appear as follows:

Easily modifying a page with Joomla 1.5

Now that we know how to modify the names and descriptions of views and layouts, we can investigate how to define custom menu parameters.

There are many different types of parameter that we can define. Before you continue, you might want to familiarize yourself with this list of parameter types because we will be using them in the examples. A complete description of these parameters is available in Appendix B, Parameters (Core Elements):

  • category
  • editors
  • filelist
  • folderlist
  • helpsites
  • hidden
  • imagelist
  • languages
  • list
  • menu
  • menuitem
  • password
  • radio
  • section
  • spacer
  • sql
  • text
  • textarea
  • timezones

Menu parameters can be considered as being grouped into several categories:

  • System
  • Component
  • State
  • URL
  • Advanced

The System parameters are predefined by Joomla! (held in the administrator/components/com_menus/models/metadata/component.xml file). These parameters are used to encourage standardization of some common component parameters. System parameters are shown under the heading Parameters (System); we cannot prevent these parameters from being displayed.

The Component parameters are those parameters that are defined in the component’s config.xml file. Note that changing these parameters when creating a new menu item only affects the menu item, not the entire component. In essence, this is a form of overriding.

This form of overriding is not always desirable; it is possible to prevent the component parameters from being shown when creating or editing a menu item. To do this we add the attribute menu to the root tag (config) of the component config.xml file and set the value of the attribute to hide:

The remaining parameter groups—State, URL, and Advanced—are defined on a per layout basis in the layout XML metadata files inside the state tag. These are the groups in which we are most interested.

The State parameters are located in a tag called params. In this example, which builds on our list.xml file, we add two parameters: a text field named revue_heading and a radio option named show_heading:

<?xml version="1.0" encoding="utf-8"?>
<metadata>
<layout title="Revue List">
<message>
<![CDATA[Summary list of revues.]]>
</message>
</layout>
<state>
<name>Revue List</name>
<description>Summary list of revues.</description>
<params>
<param type="radio" name="show_heading"
label="Show Heading"
description="Display heading above revues."
default="0">
<option value="0">Hide</option>
<option value="1">Show</option>
</param>
<param type="text" name="revue_heading"
label="Revue Heading"
description="Heading to display above the revues."
default="Box Office Revues" />
</params>
</state>
</metadata>

When an administrator creates a new menu item for this layout, these two parameters will be displayed under the heading Parameters (Basic).

The parameters are not presented under a State heading, because State and URL parameters are consolidated into one section. URL parameters always appear above State parameters.

We define URL parameters in much the same way, only this time we place them in a tag named url. The URL parameters are automatically appended to the URI; this means that we can access these parameters using JRequest.

These parameters are of particular use when we are creating a layout that is used to display a single item that is retrieved using a unique ID. If we use these parameters to define an ID that is retrieved from a table, we should consider using the often overlooked sql parameter type.

The following example builds on the previous example, and adds the URL parameter id, which is extracted from the #__boxoffice_revues table:

<?xml version="1.0" encoding="utf-8"?>
<metadata>
<layout title="Revue List">
<message>
<![CDATA[Summary list of revues.]]>
</message>
</layout>
<state>
<name>Revue List</name>
<description>Summary list of revues.</description>
<url>
<param type="sql" name="id" label="Revue:"
description="Revue to display"
query="SELECT id AS value, title AS id
FROM #__boxoffice_revues" />
</url>
<params>
<param type="radio" name="show_heading"
label="Show Heading"
description="Display heading above revues."
default="0">
<option value="0">Hide</option>
<option value="1">Show</option>
</param>
<param type="text" name="revue_heading"
label="Revue Heading"
description="Heading to display above the revues."
default="Box Office Revues" />
</params>
</state>
</metadata>

The query might be slightly confusing if you are not familiar with the sql parameter type. The query must return two fields, value and id. value specifies the value of the parameter and id specifies the identifier displayed in the drop-down box that is displayed when the parameter is rendered.

When using the sql parameter type, if applicable, remember to include a WHERE clause to display only published or equivalent items.

The Advanced parameters are specifically for defining parameters that are more complex than the State parameters. These parameters are defined in the advanced tag.

This example adds an advanced parameter called advanced_setting:

<?xml version="1.0" encoding="utf-8"?>
<metadata>
<layout title="Revue List">
<message>
<![CDATA[Summary list of revues.]]>
</message>
</layout>
<state>
<name>Revue List</name>
<description>Summary list of revues.</description>
<url>
<param type="sql" name="id" label="Revue:"
description="Revue to display"
query="SELECT id AS value, title AS id
FROM #__boxoffice_revues" />
</url>
<params>
<param type="radio" name="show_heading"
label="Show Heading"
description="Display heading above revues."
default="0">
<option value="0">Hide</option>
<option value="1">Show</option>
</param>
<param type="text" name="revue_heading"
label="Revue Heading"
description="Heading to display above the revues."
default="Box Office Revues" />
</params>
<advanced>
<param type="radio" name="list_by_cat"
label="List by Genre"
description="List revues by genre."
default="0">
<option value="0">No</option>
<option value="1">Yes</option>
</param>
</advanced>
</state>
</metadata>

Advanced parameters will appear under the Parameters Advanced heading. Component parameters, Component Design—will appear under the Parameters (Component) heading.

The resultant parameters area for this layout will appear as follows:

Easily modifying a page with Joomla 1.5

All name and description elements from the XML metadata files will be translated into the currently selected locale language.

When we save a menu item, all of the parameters, except URL parameters, are saved to the params field in the menu item record. This means that we can end up with naming conflicts between our parameters. We must ensure that we do not name any two parameters the same. This includes not using the predefined System parameter names.

This list details the System parameter names:

  • page_title
  • show_page_title
  • pageclass_sfx
  • menu_image
  • secure

Once we have successfully created the necessary XML, we will be able to access the parameters from within our component using a JParameter object. This is described in the next section.

LEAVE A REPLY

Please enter your comment!
Please enter your name here