Drupal Hooks, Controllers and Plugins Explained

By Xandermar LLC, March 24, 2024

Drupal Hooks

Drupal hooks are a fundamental aspect of Drupal's modular architecture, allowing developers to extend and customize the functionality of Drupal core and contributed modules.

Hooks are predefined PHP functions that are declared by module developers to interact with Drupal's core functionality. These functions follow a specific naming convention, such as `hook_function_name()`, where "hook" is replaced by the module's machine name, and "function_name" describes the purpose of the hook.

For example, the `hook_menu()` function is used to define menu items and pages within Drupal. Modules can implement this hook to register their own menu items and specify callback functions to handle requests to those menu items.

Hooks serve as entry points for modules to integrate with Drupal's system and respond to various events or alter the behavior of core functionality. They facilitate modularity, flexibility, and extensibility within the Drupal ecosystem, allowing developers to create custom features and functionalities without modifying Drupal core code.

Here's a simplified example of a hook implementation in a Drupal module:

 * Implements hook_menu().
function mymodule_menu() {
  $items = array();
  // Define a menu item
  $items['mymodule/custom-page'] = array(
    'title' => 'Custom Page',
    'page callback' => 'mymodule_custom_page_callback',
    'access callback' => TRUE, // Allow access to everyone
    'type' => MENU_CALLBACK,
  return $items;
 * Page callback for the custom page.
function mymodule_custom_page_callback() {
  return 'This is a custom page!';

In this example:

- `mymodule_menu()` is implementing the `hook_menu()`. It defines a custom menu item with the path `'mymodule/custom-page'`.
- The `'page callback'` key specifies the function that will be called when the menu item is accessed. In this case, it's `mymodule_custom_page_callback()`.
- The `'access callback'` key determines whether the current user has access to the menu item. Here, it's set to `TRUE` to allow access to everyone.
- `mymodule_custom_page_callback()` is the callback function that simply returns a string, which will be displayed when the custom page is accessed.

This is just a basic example to illustrate how hooks work in Drupal. In a real-world scenario, the callback function would typically perform some more complex logic, such as querying a database, rendering a template, or processing form submissions.

Drupal Controllers

In Drupal, a controller is a PHP class that handles incoming requests and returns a response. It's part of the Model-View-Controller (MVC) architecture used in Drupal development. Controllers manage the logic behind rendering pages or providing data in response to user requests. They help maintain clean, organized code by separating concerns and promoting reusability.

Here's a simple example of a Drupal controller:

// File: src/Controller/HelloController.php
namespace Drupal\my_module\Controller;
use Drupal\Core\Controller\ControllerBase;
class HelloController extends ControllerBase {
  public function sayHello() {
    return [
      '#markup' => $this->t('Hello, world!'),

In this example:

- We define a controller class called `HelloController` inside the `Drupal\my_module\Controller` namespace.
- The controller extends `ControllerBase`, which provides common functionality for Drupal controllers.
- Inside the `sayHello()` method, we return an array containing `'#markup'`, which is a way to output HTML directly. Here, we're using the `t()` function to translate the string 'Hello, world!' to support multilingual sites.

This controller could be used to respond to a route defined in a module's routing file.

In Drupal, there are several types of controllers, each serving different purposes. Here's a list of common controller types and why they are used:

  1. Page Controller:
    • Purpose: Used to render full HTML pages.
    • Usage: Ideal for rendering entire pages with complex layouts and multiple components.
  2. Form Controller:
    • Purpose: Handles form submissions and processes form data.
    • Usage: Used for creating, editing, and deleting entities, as well as for custom form submissions.
  3. Ajax Controller:
    • Purpose: Handles Ajax requests and returns responses.
    • Usage: Used for implementing interactive features on web pages without reloading the entire page.
  4. REST Resource Controller:
    • Purpose: Implements RESTful endpoints to expose resources as web services.
    • Usage: Used for creating APIs to interact with Drupal entities or custom data.
  5. Block Controller:
    • Purpose: Renders blocks, which are reusable components placed within regions of a page layout.
    • Usage: Used for creating custom blocks with dynamic content or functionality.
  6. Entity Controller:
    • Purpose: Handles CRUD operations (Create, Read, Update, Delete) for entities.
    • Usage: Used for managing custom entities and their associated data.
  7. Menu Controller:
    • Purpose: Handles menu callbacks for custom routes.
    • Usage: Used for defining custom menu items and their associated callback functions.
  8. Batch Controller:
    • Purpose: Executes long-running operations in batches to prevent timeouts.
    • Usage: Used for performing resource-intensive tasks, such as data migrations or large-scale updates.

Each controller type in Drupal serves a specific role in handling different aspects of a web application, allowing developers to organize and manage functionality effectively.

Drupal Plugins

In Drupal, plugins are reusable pieces of code that extend the functionality of the Drupal core or other modules. They provide a way to add new features, alter existing functionality, or integrate with external systems. Plugins in Drupal can take various forms, such as blocks, field types, filters, and more, allowing developers to customize and extend Drupal sites according to their specific needs.

Here's a simple code example of a custom Drupal plugin:

// Create a custom module called "custom_plugin_example".

// Define the plugin annotation.
 * @file
 * Contains \Drupal\custom_plugin_example\Plugin\ExamplePlugin.
 * @Plugin(
 *   id = "example_plugin",
 *   label = @Translation("Example Plugin"),
 *   description = @Translation("An example Drupal plugin."),
 *   category = @Translation("Custom")
 * )

// Create the plugin class.
namespace Drupal\custom_plugin_example\Plugin;

use Drupal\Core\Plugin\PluginBase;

 * Provides an example plugin.
 * @Plugin(
 *   id = "example_plugin"
 * )
class ExamplePlugin extends PluginBase {

   * {@inheritdoc}
  public function doSomething() {
    // Custom functionality of the plugin.
    return "This is an example plugin doing something.";


This code defines a custom Drupal plugin called "Example Plugin" in the module "custom_plugin_example". The plugin provides a method doSomething() that returns a simple string indicating its functionality. You would need to place this code in the appropriate files within your custom Drupal module directory structure and ensure the module is enabled in your Drupal site.