35

Is it possible to create your own hook in a Drupal module for other Drupal modules to consume? If not, is there a mechanism in Drupal for third party developers to provide hooks? If everything's been a no so far, where in the core are the list of hooks implemented?

As I understand things, Drupal modules work on a event like system called hooks. When you create a new module, you create functions that implement a hook. For example, there's a hook_delete hook. If you implement a function in your module

function mymodule_delete($node)
{
}

this function will be called whenever a node is deleted.

What I want to know is, is there a way or me, as a third party module developer, to create my own hooks. Say, something like hook_alanskickbutthook so that other module developers could subscribe to this hook.

If this is possible, how do you do it? I've looked around the official docs and haven't found much there, and I still get a little dizzy when I start poking around the Drupal source code (I understand recursion, but don't spend enough time thinking about recursive problems). Full solutions are welcome, but I'm happy to just be pointed in the right direction.

Alan Storm
  • 157,413
  • 86
  • 367
  • 554

4 Answers4

39

Module_invoke_all() is your ticket to creating your own hooks:

see the API:

http://api.drupal.org/api/drupal/includes--module.inc/function/module_invoke_all

and then look at this great writeup:

http://web.archive.org/web/20101227170201/http://himerus.com/blog/himerus/creating-hooks-your-drupal-modules

(edit: was at http://himerus.com/blog/himerus/creating-hooks-your-drupal-modules but this is now gone)

Once you've made your hook, it can be called in another module using:

/**
 * Implementation of hook_myhookname()
 */

function THISMODULENAME_myhookname(args){
  //do stuff
}
jpstrikesback
  • 2,314
  • 14
  • 18
  • In the tutorial you posted, what's calling the "taxonomy_rockstar_generate_layouts" function? (apologies for the newbie-style question. I'm new enough to Druapl that I can't quite tell where things belong in the system). – Alan Storm Feb 14 '11 at 16:37
  • 4
    Some corrections/tipps: a) $args is not by reference when using module_invoke_all(). b) If you want to pass something by reference, use either drupal_alter() (forces '_alter' suffix on hook name) or module_implements + a loop and then call the implementations directly. c) The recommended way to document hooks is in a yourmodule.api.php file, see core for examples. d) A common pattern in D7 when collecting information if to use an info suffix and also call drupal_alter on that. Example . – Berdir Feb 14 '11 at 17:41
  • good catch on the reference...I was thinking of drupal_alter() when I added it, edited – jpstrikesback Feb 14 '11 at 17:46
  • @jpstrikesback thanks for the clarification. One more clarifying question. **Where** should you be calling module_invoke_all from? Am I correct that you'd implement one of the core module's early hooks and put it in there? Or something else? – Alan Storm Feb 14 '11 at 18:06
  • Often you are creating a hook to allow another module modify some data right before you do something with it (and you might use the hook in your own module as well). In that case I would place the module_invoke_all() right before doing something with the data. For examples check out [drupal_goto](http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_goto/6) and then [Here is another good tutorial/example](http://www.trellon.com/content/blog/hooks-api). – jpstrikesback Feb 14 '11 at 18:22
  • first link is dead :( blog has been removed stackoverflow.com/questions/4999828/what-ties-a-drupal-hook-to-a-particular-module you may want to look at this link too – Karel-Jan Misseghers Mar 21 '12 at 10:20
  • Thanks Karel-Jan, I've updated the link with the wayback machine copy of the page – jpstrikesback Mar 22 '12 at 01:58
6

For example, say you wanted to create hook_my_custom_goodness() for others to use. Then just place code like this in your module at the point where you want the hook to happen:

$variables['msg'] = 'foo';

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

drupal_set_message($variables['msg']); // Will display 'bar' instead.

Now, if anybody wanted to use your hook, then they could do so in their own module like this:

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

There is a more complete explanation here:

http://tylerfrankenstein.com/code/drupal-create-custom-hook-for-other-modules

tyler.frankenstein
  • 2,085
  • 1
  • 22
  • 33
0

For Drupal 6 & 7, drupal_alter() is probably the best option.

As stated in the module_invoke_all() documentation,

All arguments are passed by value. Use drupal_alter() if you need to pass arguments by reference.

In Drupal 8, use ModuleHandler::alter.

Passes alterable variables to specific hook_TYPE_alter() implementations.

colan
  • 2,508
  • 1
  • 17
  • 17
0

If i recall... http://api.drupal.org/api/drupal/modules--node--node.api.php/function/hook_delete/7

does ths help? been a while since I messed with Drupal.

To create/offer custom Drupal hook, you must implement in a ways such that calling the hook with module_invoke or module_invoke_all does not make any conflicts with other module hooks. The name of the hook should be unique and it should offer all/specific feature in such a general way that it doesn't require any type of adjustments with code. All the configuration must go on admin pages and should store those configurations in a separate table or any existing tables create by Drupal or modules on which your modules depends. The hook should be easy to implment by other modules and it should not be much complex to implement. When you create custom hooks, your module(s) act(s) as API provider.

Brian
  • 7,632
  • 2
  • 22
  • 32