Problem/Motivation
drupal_set_message() sets a message to display to the user. This messages cannot be modified from other modules, or customized in a given site.
Proposed resolution
Add a hook_messages_alter() function.
Remaining tasks
- Check if this compromise solution is still on time for D8.
- Write tests.
User interface changes
None.
API changes
drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE)
becomesdrupal_set_message($message = NULL, $type = 'status', $message_key = NULL, $repeat = FALSE)
- API addition: hook_messages_alter()
Original report by @Gman
Originally noted at http://www.tech-wanderings.com/Drupal-hook_message_alter, I want to propose a new hook, hook_message_alter.
As I have been working on the functional implementation for a new community Drupal site, I have been seeing the need to customize many of the core Drupal messages (the drupal_set_message function), as required by the needs of the site. A typical example would be when a contact message has been sent, the default message is 'The message has been sent.' An small change might be to 'Thank you, your message has been sent.' A more dynamic change would be 'Thank you Greg, your message has been sent'.
The first change could be accomplished using the locale module methodologies found in http://drupal.org/node/58030. But there are two short-comings to this method. First, even though all core modules use t() for the text to make it translation ready, many contributed modules do not. Second, the translation method only allows for string replacements, not dynamic insertions. Granted some of the messages place the user's name or other dynamic information into the message, but the basic idea is that you can only change what is given you, you can't add to it. The contact message is a perfect example, there is no way to add the user's name to the message.
That is why I am going to propose a new drupal hook, hook_message_alter(&$message = NULL), allowing the $message to be changed by reference. It would hook into the drupal_set_message function. All messages would invoke this hook, giving designers and developers the ability to customize those messages completely to suit their site.
Since the purpose of hooks is to 'Allow modules to interact with the Drupal core', then this hook is needed for any time that the core (or any contributed) messages are not composed the way a site owner would want them to be.
This hook would most likely be used as part of theming/customization of site, and thus not used much in a contibuted module, though it may be used in a contibuted theme if the designer wanted to update the message prose. Personally I would use such a hook to dynamically insert text into the messages at key points in the user experience (especially if I am seeking to make certian conversion points of a client's site personalized).
The new drupal_set_message would pass the $message by reference and change to:
function drupal_set_message($message_id, $message = NULL, $type = 'status') {
if ($message) {
if (!isset($_SESSION['messages'])) {
$_SESSION['messages'] = array();
}
if (!isset($_SESSION['messages'][$type])) {
$_SESSION['messages'][$type] = array();
}
foreach (module_implements('message_alter) as $module) {
$function = $module .'_message_alter';
$function($message);
}
$_SESSION['messages'][$type][] = $message;
}
// messages not set when DB connection fails
return isset($_SESSION['messages']) ? $_SESSION['messages'] : NULL;
}
With an implementation of a hook looking like:
function example1_message_alter (&$message = NULL) {
if (strcmp($message, 'The message has been sent.') {
global $user;
$message = 'Thank you ' . $user->name . ' for contacting us. Your message has been sent.';
}
}
The return value is discarded. Modify the $message directly.
Please let me know any of your thoughts, as I will present this as an issue at Drupal.org once I have better composed this idea. -Greg