Howdy. Hopefully this won't be so bad. I'm just trying to customize a system message (drupal_set_message) on redirect after submitting a form for creating a node. The redirect is working fine and I've located the message that I want to alter. It is set in node_form_submit with this function:

function node_form_submit($form_id, $form_values) {
  global $user;

  // Fix up the node when required:
  $node = node_submit($form_values);

  // Prepare the node's body:
  if ($node->nid) {
    watchdog('content', t('@type: updated %title.', array('@type' => t($node->type), '%title' => $node->title)), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
    drupal_set_message(t('The %post has been updated.', array('%post' => node_get_types('name', $node))));
  else {
    watchdog('content', t('@type: added %title.', array('@type' => t($node->type), '%title' => $node->title)), WATCHDOG_NOTICE, l(t('view'), "node/$node->nid"));
    drupal_set_message(t('Your %post has been created.', array('%post' => node_get_types('name', $node))));
  if ($node->nid) {
    if (node_access('view', $node)) {
      return 'node/'. $node->nid;
    else {
      return '';
  // it is very unlikely we get here
  return FALSE;

I tried using hook_form_alter to change the submit handler based on some information I found here and here I basically copy pasted the above function and changed the drupal_set_message to what I wanted and used this syintax $form['#submit']['my_very_own_submit'] = array(); to change the submit function from node_form_submit to my version of node_form_submit that has the altered message. It worked except it seems to run BOTH submit functions, as the message show up twice (once normal and once with my changes) and the node is created twice.

Would someone show my how you can write this so that only the alternate submit function is run, not both?


arcaneadam’s picture

Rather then try alter the submit function which as you can see won't really work the way you want, just use your submit function to alter the $_SESSION['messages'][$type] variable. something like this may work:

$key = array_search("has been created.",$_SESSION['messages']['status']);
$_SESSION['messages']['status'][$key] = "Your message Overide";

I've not tested this out but am pretty sure it would work.

Adam A. Gregory
Drupal Developer and Consultant
Acquia Certified Developer-Back end Specialist

mjlF95’s picture

That worked beautifully. Thank you very much. Apparently I was barking up the wrong tree even though I was in the right forest. :)

I've only just recently started doing var_dump on forms and using hook_form_alter to customize some things here and there. I've been looking at the form api reference for help. I've never used a technique like you showed me here by changing the contents of variables. Is there any documentation available on this? Thanks again for the help.

Hunabku’s picture

The above suggestion will not work because array_search will not find the sub string "has been created." Also you can create a more universal solution with nodeapi.

For Drupal 6 Try:

function your_module_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  switch ($op) {
    case 'view':
      global $_SESSION;
      if ($_SESSION['messages']['status']) {
          foreach ($_SESSION['messages']['status'] as &$value) {
            if (substr($value, -17) == 'has been created.') {
              $value = $your_var_etc . ' has been created.'; //put whatever you want here

for a more specific solution geared to altering form submits see:

kpv’s picture

This will not work, when the user is redirected, after node is submitted. This is because the node could be not shown on the page, user is redirected to. But you rely on this (in case 'view').

So, another solution (for D6):

  function yourmodule_form_alter(&$form, $form_state, $form_id){
    //Check form id
    if($form_id == 'your_form_id'){

      //Redirect to the front page (or any other)
      //$form['#redirect'] = '';
      //Add your function here
        $form['buttons']['submit']['#submit'][] = 'yourmodule_submit_function';

  function yourmodule_submit_function($form, &$form_state){
    global $_SESSION;
    //If a new node is added, but not updated
    $insert = empty($form_state['values']['nid']);
      //Get the last 'status' message (it is always added if node_form_submit)
         //For more reliability you can check whether the preceding 'submit' function
         //is 'node_form_submit' (see for more detail)
      $keys = array_keys($_SESSION['messages']['status']);
      $last_key = end($keys);
      //Write your message text here
      $message = 'text';

      //Substitute default message by yours
      $_SESSION['messages']['status'][$last_key] = $message;

      //Or just unset the message
      //(you should unset also $_SESSION['messages']['status'] if there are no more 'status' messages)
nagiek’s picture

This is the solution I'm going with.

mooffie’s picture

If you just want to unconditionally change the message, see the comment about "String overrides" in [default.]settings.php (for D6 and up).

kpv’s picture

Thanks, it is really a useful feature.
Although, as i understand, it can't be used to change messages per node type.

Also can be used

kenorb’s picture
You can write your own custom rules to change default drupal set messages.

sitael’s picture

Guys, I don`t know if this is the best solution...but worked for me.

On module I made a function like this

//this is equal as node_form_submit overriding what I want.
function mycustom_function_submit($form, &$form_state) {
  $node = node_form_submit_build_node($form, $form_state);
  $insert = empty($node->nid);
  $node_link = l(t('view'), 'node/' . $node->nid);
  $watchdog_args = array(
    '@type' => $node->type,
    '%title' => $node->title,
  $t_args = array(
    '@type' => node_type_get_name($node),
    '%title' => $node->title,

  if ($insert) {
    watchdog('content', '@type: added %title.', $watchdog_args, WATCHDOG_NOTICE, $node_link);
    drupal_set_message(t('@type %title has been created. OVERRIDED', $t_args));
  else {
    watchdog('content', '@type: updated %title.', $watchdog_args, WATCHDOG_NOTICE, $node_link);
    drupal_set_message(t('@type %title has been updated.', $t_args));
  if ($node->nid) {
    $form_state['values']['nid'] = $node->nid;
    $form_state['nid'] = $node->nid;
    $form_state['redirect'] = 'node/' . $node->nid;
  else {
    // In the unlikely case something went wrong on save, the node will be
    // rebuilt and node form redisplayed the same way as in preview.
    drupal_set_message(t('The post could not be saved.'), 'error');
    $form_state['rebuild'] = TRUE;
  // Clear the page and block caches.

and on the function MYMODULE_form_alter I override the call of function

function seisd_system_form_alter(&$form, $form_state, $form_id) {
        case 'id_of_my_form':
              $form['buttons']['submit']['#submit'][0] = 'mycustom_function_submit';

Hope this helps.