The messages model allows you to externalise the messages used in your website to enable these to be easily shared and changed and to facilitate translation into other languages.  Even if you are only planning to develop your website in a single language it is generally unwise to "hard code" messages within your business logic. The messages model makes it easy to externalise these messages. Behind-the-scenes, these messages are stored in text files under the private_data messages folder.

Organizing Messages

The messages model allows any number of messages to be grouped together in a single message definition. Nevertheless, each message is stored as a separate text file when the definition is stowed. For small applications (sites), you might decide to group all of the application's messages into a single message definition. However, if your site has more than say a 20 or 30 messages you probably want to group these into multiple definitions. Generally, you will want to arrange messages that tend to be used together into the same message definition.

system Messages

As with many other aspects of the framework, messages can be inherited from other sites, including system. When defining messages it is important to ask yourself whether other systems are likely to require the same message. If the answer is "yes", it is best to define the messages within the system site where it can be inherited by all sites.

Making Messages Generic Yet Informative

Consider the message "Record not found".

One can certainly say that this is a generic message that could be used by many different pages. On the other hand it is not very informative because it does not say anything about which record could not be found. If we change this message to something like "Your student record could not be found", the message becomes more specific and informative however, it also becomes less generic and reusable. Let's see how message placeholders can be used to make message more informative while, at the same time, making them more reusable.

Message Placeholders

Messages can contain any number of placeholders in the form :n: where n is a number starting at 1 and incremented by 1 for each placeholder. Consider the message:

:1: record :2: was not found

Since this message contains placeholders, it can be "adjusted" at runtime to contain meaningful data. One page could render this message as:

Student record 73513 was not found

While another program could render this same message as:

Country record ZW was not found

By using placeholders, many messages may become generic enough that you might want to define them within system where they can be shared by any site. In fact, the framework comes with a number of system messages in the general definition including the following:

general system messages

Notice that placeholders may be defined in both the message text and the tooltip text which is shown when the user hovers over the message. The same or different placeholders can be used in each case. Often :1: is defined before :2:, etc. however this is not a requirement. When messages are translated into different languages, it may happen that :2: appears before :1: in the translation.

Displaying Messages

In order to take advantage of standard message handling, PHP classes should extend the base class called standard_base. For example:

require_once CLASS_PATH.'standard_base.php';
class myclass extends \standard_base;

The main method used to assign a message from generated messages is assign_message. For example:

$this->assign_message('!flexgrid',2025,array($label,$this->flexgrid_description,$row['#']),
                      'Value of :1: on :2: row :3: cannot be empty',__LINE__.' '.__CLASS__);

Let's review the parameters to the assign_message method:

Message Definition

The first parameter identifies the subfolder where the message is stored. This coincides with the name you used to stow the message specification. Notice that, in the example, this starts with !. This tells the message handler to look in the system site for this message. If the message definition is stored within the current site, do not prefix the definition name with !.

Message Number

The next parameter is the 4-digit message number.

Placeholder Values

The third parameter defines the values to be copied into the placeholders. If the message you are requesting does not contain any placeholders you can pass false or null in this position. If there is only one placeholder in the message, you can pass a scalar (sting or number). If there are several placeholders in the message it is necessary to pass an array containing the placeholder values. array[0] will be assign to placeholder :1:, array[1] will be assigned to placeholder :2:, etc.

Message Text

The message text is only used if the requested message is not defined. In such a case, the supplied text will be used as the fallback message. It is a good idea to copy the message text into this parameter since it makes the program easier to read and understand since the message serves as a comment.

Message Location

The final parameter tells the message handler the name of the module and line that triggered the message. This information is shown when the user hovers their cursor over the message. This is useful for debugging purposes. Be aware that the location information will be shown to the user. For certain sensitive applications, knowing the name of the program that issued a message could be considered a security vulnerability (even though your website users won't be able to access the class code even if they know its name). For most applications, the benefit (to developers and support staff) of knowing where a message was set will outweigh the risk of exposing this information to your users.

Transferring Messages from one Class to the Next

Often when one class calls another class and the second called class raises an error, the first called class might want to harvest the second class' messages and return these to its caller. This can be done by calling the method transfer_your_messages_to_me. Here is an example of a typical use of the method.

$success = $some_class->do_something();
if (!$success) {
    $some_class->transfer_your_message_to_me($this);
    return false;
}

Using this method, lower level messages can be percolated up to higher levels in the call chain. For more details on transferring and showing messages please review the custom model help.

Rendering Message Responses

If an object you have called sets a message by calling its assign_message function but you don't inherit standard_base or have access to a form that can render the message you can always ask the object to return the message so that you can render this as you require. In this example we call the obtain_message method of an object to get the message(s) formatted as html.

$cust = $cust_api->get_customer_details($email);
if ($cust === false) {
	$formatted_msg = $cust_api->obtain_message();
}

By default, the obtain_message method will clear the message from within the called object. To prevent this, you can pass false in parameter 1. Also, the default behavior is to the return the message in HTML format as illustrated here:

<div class="alert-danger" title="!invoice_admin(1016) / 91 customer_api">
  &#9940;1016 Customer information associated with email address fred@slater.com was not found.
</div>

If you simply want the text for the messages you can pass true in parameter 2 of the obtain_message method. By default, multiple messages will be separated by a newline character. You can supply an alternate separator in parameter 2 as we show here:

return $cust_api->obtain_message(true,'<br />');

Using $message Dollar Function

Another way to retrieve a message is using the $message function. Here is an example of this function:

$message(!general,0001,name)

Translating Messages

One of the advantages of defining external messages is that it makes it easier to internationalize applications since messages can be translated into other languages without changing the program logic. Translated messages are saved using the translate_messages model.

The message_area object

Message rendering is handled by the message_area object defined within a codeframe. Supplied codeframes support conditions which allow the message location to be adjusted either sitewide (in site_settings) or within specific layouts. The default location for rendering messages is identified as below-banner. This can be adjusted to either above-banner or below-navigation. Here we show a layout in which the message_location has been set to above-banner.

Setting Codeframe Conditions within a Layout.

Messages are commonly used in conjunction with forms. When using components generated by the form_handler model the interaction with the message_area object is handled automatically by the GenHelm framework. When using other models, such as the custom model, it is necessary to programmatically pass messages to the message_area object if you want this object to render the messages. Sometimes components can run in different layouts which may or may not include a message_area object. In such a case it is advisable to confirm that your layout supports message_area before attempting to interact with it. Here we show an example of how this can be done.

// Call an object that extends the standard_base class
$rows = $sql_handler->fetch_all_rows($sql,$sql_parms,'sakila');
if ($rows === false) { // SQL error
  	// The called object contains messages that we want to show to the user,
  	// If we are running within a layout that supports the message_area
  	// object pass the messages to that object to render.
	$message_object = $this->site->layout->get_object('message_area');
	if ($message_object) {
		$sql_handler->transfer_your_messages_to_me($message_object);
		return 'Error processing the request';
	}
	else {
      	// There was no message object, just fetch the message text and
      	// return this to my caller to render on the screen.
   		return $sql_handler->obtain_message(true,true);
	}
}

Rendering Messages in a Popup Window

By default, the message_area object renders messages on screen. Config settings can be used to request that messages be rendered in a popup. Once again this setting can be made at the layout level or the site level. Here we see this config setting within site_settings..  

Adjusting the config settings to render messages as popups

This is a sample specification for messages model
🡇
This is a sample rendered message