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.
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.
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.
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:
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.
In order to take advantage of standard message handling, PHP classes should extend the base class called standard_base. For example:
The main method used to assign a message from generated messages is assign_message. For example:
Let's review the parameters to the assign_message method:
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 !.
The next parameter is the 4-digit message number.
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 will be assign to placeholder :1:, array will be assigned to placeholder :2:, etc.
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.
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.
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.
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:
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:
Using $message Dollar Function
Another way to retrieve a message is using the $message function. Here is an example of this function:
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.
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.
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..