So, you want to allow other modules to hook into your own module. You may have implemented hooks that other modules provide, but does invoking your own hook for a module seem like a dark art? It is as simple as calling one function in your module. All will be revealed shortly, but first, lets look at why you would want to invoke your own hook.

What is invoking a hook?

When you invoke a hook, you are registering a new hook with Drupal that allows other modules to implement and therefore interact with your module. You are providing hook in points in your module which say to other modules “here is a point where you can inject your own data or extend my module”.

Why invoke hooks?

The hook system is at the heart of what makes Drupal powerful. All modules will use hooks to interact with the rest of the Drupal system. By invoking your own hook, you are making your module more powerful and useful because you are allowing other modules to extend it or change its data in some way. If no module invoked hooks, there would be no hooks for you to implement! If it still does not make sense, don’t worry, as the best way to understand it is with an example.

Beer round example

Let’s take a really simple example. Imagine you have a module with some code which returns a list of people included in a round of beer. And then you want to invoke your own hook so that other modules can add to the list of names that are part of the beer round.

Let’s set the module up before invoking the hook. The module is called beer_round. In beer_round.module you firstly need to implement hook_menu() to define the path where we can see the list of names for the beer round.

/**
 * Implements hook_menu.
 */
function beer_round_menu() {
  $items = array();

  $items['beer'] = array(
    'title' => 'Beer round',
    'page callback' => 'beer_round_callback',
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK,
  );

  return $items;
}

This snippet simply means, when the user goes to the path beer, call the callback function called beer_round_callback(). Anyone who has the access content permission has the necessary permissions to view this page.

Next you need to define the callback function.

/**
 * List of people included in a round of beer.
 */
function beer_round_callback() {
  $round = array('Dave', 'Paolo', 'Andrew', 'Mat', 'Paula', 'Mihhail', 'Pete', 'Dima', 'Bhavna', 'Laura', 'Steve', 'San', 'Nick');
  $output = theme('item_list', array('items' => $round));

  return $output;
}

This contains an array of names of people who are part of the beer round. You then pass that array into the theme() function, which will convert it into an unordered list. If you now hit the path beer, you will see the list of names.

Blair added to the beer round after implementing hook_beer_round

Now it is time to invoke a new hook. To invoke a new hook, all you need to do is call module_invoke_all() and pass in the name of the hook. We will call the hook beer_round. So you will call module_invoke_all(‘beer_round’) and add the result to the array of people in the round.

/**
 * List of people included in a round of beer.
 */
function beer_round_callback() {
  $round = array('Dave', 'Paolo', 'Andrew', 'Mat', 'Paula', 'Mihhail', 'Pete', 'Dima', 'Bhavna', 'Laura', 'Steve', 'San', 'Nick');
  $round_more = module_invoke_all('beer_round');
  $round_all = array_merge($round, $round_more);
  $output = theme('item_list', array('items' => $round_all));

  return $output;
}

Drupal will check every module to see if hook_beer_round has been implemented. If it has, the data the modules provide will be added to $round_more, which will be an array. If two modules implement hook_beer_round(), the array will contain two elements. So now we have two arrays, the original array of people in the beer round, and the additional people added via the hook. So merge the two together with array_merge(), and you have the full round.

To see this in action, implement hook_beer_round() in another module. I have a module called ‘blair’ where I will add myself to the beer round.

My implementation of hook_beer_round is:

 /**
 * Implements hook_beer_round();
 */
function blair_beer_round() {
 return 'Blair';
}

Now if you reload the beer page, you will see that my name has been added.

Blair added to the beer round after implementing hook_beer_round

That is all there is to invoking a hook! This is a very simple example to get you started. I will go into a more advanced example in a future post.

Note: real names are used in the example, but nobody was harmed in the production of this tutorial.

Overview of invoking a hook

Overview of invoking a hook