Last updated October 24, 2018

Hooks allow modules to alter and extend the behavior of Drupal core, or another module. They are one of the various ways that code components in Drupal can communicate with one another. Using hooks a module developer can change how core or another module works -- without changing the existing code. As a Drupal developer, understanding how to implement and invoke hooks is essential.

In this tutorial we'll:

  • Define what hooks are and the types of hooks that exist
  • Understand the use case for hooks

Goal

Understand what hooks are and how they are used in Drupal. Be able to know where to find information about implementing and invoking hooks from your custom code.

Prerequisites

What Are Hooks?

Hooks

From an implementation perspective hooks are specially-named functions called at specific times to alter or add to the base behavior. Each hook has a unique name (example: hook_entity_load()), a defined set of parameters, and a defined return value.

Every hook has three parts; a name, an implementation, and a definition. The implementation consists of the custom code in your module that you want to execute. Another module or subsystem provides the definition, which specifies the hook's name and which arguments are passed to the implementation, as well as when the implementation will be called.

Any number of modules can implement the same hook. This allows multiple modules to contribute to the final outcome. For example, you might have two or three different modules enabled that implement hook_toolbar() in order to add links to the administration toolbar. Each implementation (function) will be called in order based on the module's weight stored in the core.extension configuration object, which can be viewed using Drush with drush cget core.extension. If multiple modules have the same weight they will be called in alphabetical order based on the module's machine name. (Note: drush cget is shorthand alias for both the Drush 8 command drush config-get and the Drush 9 command drush config:get.)

A naming convention

At their most basic, hooks are a naming convention. Define a PHP function whose name follows a known pattern, and Drupal will call that function at critical points during the life cycle of a request. Just replace the word HOOK in the hook definition with the machine name of your module, and presto, you've implemented a hook.

This:

HOOK_entity_load()

Becomes:

mymodule_entity_load()

What can I do with hooks?

Things you can do with hooks:

Types of hooks

Generally you can place hooks into one of three categories:

  • Hooks that answer a question
  • Hooks that alter existing data
  • Hooks that react to an action

Hooks that answer questions, often referred to as "info hooks", are invoked when some component in Drupal is gathering a list of information about a particular topic. For example, a list of all the items that should be displayed in the toolbar, or a of requirements to verify prior to installation. These hooks primarily return arrays whose structure and values are determined by the hook definition. The user module is a good example of this: see user_toolbar() which adds links to common user account pages to the Toolbar.

Note: Drupal 8 has fewer info hooks than previous versions of Drupal. Prior to Drupal 8, info hooks were the primary way of gathering new lists of functionality. Now, the plugin system generally handles this.

Hooks that alter existing data, often referred to as "alter hooks", and identifiable by the fact that their names are suffixed with _alter, are invoked in order to allow modules to alter a list of previously gathered information. These are often paired with info hooks. A component may first invoke an info hook to gather a list of information, then immediately invoke an alter hook to allow anyone to alter the list that was just created before it's used. You might, for example, change the order that items are listed in the Toolbar, or even change the name used for an item added by another module. The taxonomy module has an example of this: taxonomy_views_data_alter(), which adds taxonomy term fields to the information about nodes provided to the views module.

Of special note is hook_form_alter(), one of the most powerful, and likely most commonly implemented hooks. hook_form_alter() allows modules to alter the Form API arrays generated by other modules, thereby modifying, and participating in, every aspect of the form generation, validation, and submission workflow. Taking some time to explore examples of hook_form_alter() in use is a great way to get ideas for how your module might affect the way Drupal works.

Hooks that react to an action, similar to events, are invoked when specific actions are taken in code somewhere in the system in order to allow other code to do something based on that action. For example, hook_user_cancel() is invoked every time a user account is canceled. Modules that store data about users that need to perform cleanup tasks can implement this hook to be notified about the account that is being canceled and take the necessary actions on their own data. The comment module is a good example of this, see comment_user_cancel() which removes comments created by a user when their account is canceled.

Recap

In this tutorial, we learned that hooks are composed of three parts: a name, an implementation, and a defintion. We learned about the naming convention for hooks as well as three kinds of tasks you can perform with a hook: discover existing hooks, implement a hook, and define (invoke) a new hook. Finally, we learned about the types of hooks: hooks that answer a question, alter existing data, or react to an action.

Further your understanding

  • How do hooks relate to plugins and events?
  • Can you find an example of an implementation of a hook in Drupal core? Which one did you find? What do you think this particular implementation is doing?

Additional resources