Drupal - Create a Custom Hook for Other Modules to Use

Category:

In this example, we'll explore how to make a custom hook with our module so that other modules may use it.

For example, say we were implementing hook_entity_delete() to display a custom message whenever an entity was deleted. But before we display the message, we want to allow other modules to modify the message if they want. We would do that by 'creating' a custom hook by using module_invoke_all(), like so:

In the code example below, we'll 'create' a hook called: hook_change_my_entity_delete_message()

/**
 * Implements hook_entity_delete().
 */
function MY_MODULE_entity_delete($entity, $type) {
  
  // Create our message variables.
  $variables = array('msg' => 'foo');

  // Make sure at least one module implements our hook.
  if (sizeof(module_implements('change_my_entity_delete_message')) > 0) {
    // Call all modules that implement the hook, and let them make changes to $variables.
    $variables = module_invoke_all('change_my_entity_delete_message', $variables);
  }

  // Display the message.
  drupal_set_message($variables['msg']);
}

Now if another module wanted to implement this hook and change the message, they could do that like so:

/**
 * Implements hook_change_my_entity_delete_message().
*/
function SOME_OTHER_MODULE_change_my_entity_delete_message ($variables) {
  $variables['msg'] = 'bar';
  return $variables;
}

Now when an entity is deleted, our implementation of hook_entity_delete will get called and get ready to display the message, then call any module that implements hook_change_my_entity_delete_message(), then return and print out $variables['msg'].

Which in this case the drupal_set_message would display: bar

Comments

you can use drupal_alter() too for altering purposes

Hi Jason,

Thank you for pointing out drupal_alter(). Now I feel like I should have used that function instead, and will look to that in the future as it seems it could provide a cleaner approach than what is implemented in this post.

Thanks Tyler,

Very helpful. A lot simpler than I thought it was going to be. The documentation for drupal_alter seems to be rather obtuse. If you do a revised blog post using that method let me know. :)

Thanks Chris. I actually just used drupal_alter() for the first time the other day.

From the code above, this line here would replace the line with the call to module_invoke_all()

drupal_alter('change_my_entity_delete_message', $results);

Then any implementers of the hook would use a function template like this:

/**
 * Implements hook_change_my_entity_delete_message().
*/
function SOME_OTHER_MODULE_change_my_entity_delete_message (&$variables) {
  $variables['msg'] = 'bar';
}

That should work! (didn't test it though)

hook_change_my_entity_delete_message_alter()

You forget the _alter :).

Tyler,

Great blog post and I think drupal_alter() is great, but you also could make it even simpler by using a regular variable without the $variables array and just passing a non-array variable with a reference:

Instead of  $variables = array('msg' => 'foo'); you could simply use $message="foo"

Then, when the hook is implemented, it could use:

/**

 * Implements hook_change_my_entity_delete_message().
*/
function SOME_OTHER_MODULE_change_my_entity_delete_message (&$message) {
  $message = 'bar';
}

What you did works as well. Either way would work.

BC