Using Drupal Hooks: Tapping into Drupal's Core Functionality


Drupal started as a message board by Dries Buytaert in 1999 and was released as an open source content management system in 2001. Since then the Drupal community has rapidly grown and made Drupal into one of the most popular and powerful content management systems on the planet.

I could go into all the specific reasons why Drupal is so powerful that 2.7% of all websites in the world use it (including Colorado.gov) and why we at Chronos develop a large number of our sites using Drupal as a CMS framework — but that's a topic for another post. What I want to cover today is how to harness the power built into Drupal’s core using hooks.


What are hooks?

The most basic explanation of hooks is that they are PHP functions that extend or 'hook' into the core functionality built into Drupal. Out-of-the-box Drupal has many features that allow developers to build robust websites, but quite often they need to add or modify custom functionality. Using hooks you can create url paths or custom pages, alter how Drupal outputs markup by default, set up custom access rules, and even tell Drupal to vacuum your house. Okay that last one is a stretch but give it time.


How to use hooks

One of the things that makes Drupal so great is the modules created and contributed by the Drupal community. Modules are made up of various hooks and functions to create custom features and functionality in Drupal. In an article posted by the community on Drupal.org they explain that “because the module code executes within the context of a the site, it can use all the functions and access all variables and structures of Drupal core.” The hooks are what tie into Drupal core and modules are where the hooks live.

A basic analogy is to think of a panel of 3 light switches for different color lights—red, green and blue. Each light switch represents a module with a hook or function that tells the power source which light to turn on and off. If I turn on the blue switch the hook fires and tells system to supply power to the blue light.

In Drupal, you enable and disable modules just like the light switch. I may have a module that, when enabled, fires a hook that tells Drupal to create a page that only certain users have access to.


You lost me, do you have an example?

One basic example is adding classes to markup that Drupal creates by default.

Let's say I’ve created a form using Webform and I’m trying to theme it by adding my own custom class to the markup. Because Drupal and the Webform module spit out the output, you need a way to tie or hook into the core functionality to add the class.

First, you create a custom module (there are detailed instructions on how to create a basic, blank module here). In every module is a .module file, where the majority of your code will go. The .module file is named after the module so if we named our module 'Custom Classes' then the file name would be custom_classes.module. Inside that module we’re going to use a hook called hook_form_alter. This particular hook allows us to take either one form in particular, a set of forms, or even all forms on the site and alter them somehow.

Lets take a look at the code we would use to add a class to the form:

/**
* Implements hook_form_alter().
*/
function custom_classes_form_alter(&$form, &$form_state, $form_id) {
     if ($form_id == ‘webform_client_form_1') {
          $form[‘actions’][‘attributes’][‘class’][] = ‘customclass’;
     }
}

The first part of the code is a Doxygen style comment that states we are using a Drupal hook. This is part of Drupal coding standards and helps identify when the developer is using a Drupal hook as opposed to a custom function. See Doxygen and comment formatting conventions for more details.

The next section is the hook itself. Notice instead of using “hook_form_alter” we used “custom_classes_form_alter”. This is because the hook needs to use the name of the module it resides in instead of the word hook.

Within the hook we use an if statement to check the ID of the form we want to alter. By default, Drupal creates an array of classes to add to the markup. What we want to do is add our class “customclass” to that array using the code within the if statement.

Once that is done we just ensure that our module is enabled in Drupal, flush our cache and then check our form markup to see that our custom class has been added.


Want another example? Let’s create a page programmatically

*Note: this example will only work in Drupal 7

Sometimes we need to create a custom page and doing it programmatically is the better option. Say, for example, we want to create a help page within the admin section that has some basic instructions for adding a blog post.

We could create a module called Site Help and in the site_help.module file we’ll use hook_menu, which “enables modules to register paths in order to define how URL requests are handled. Paths may be registered for URL handling only, or they can register a link to be placed in a menu (usually the Navigation menu).”

There’s a lot you can do with this hook but we’ll use a very basic example to create an admin page to list help.

/*
* Implements hook_menu().
*/
function site_help_menu() {
     $items[‘admin/addbloghelp’]= array(
          ‘title’ => ‘How to add a blog post’,
          ‘description’ => ‘Detailed instructions on how to publish a blog post’,
          ‘page callback’ => ‘blog_help_page’,
          ‘access arguments’ => array(‘access administration pages’),
     );
     return $items;
}
 
/*
* Custom function to call blog_help.tpl.php
*/
function blog_help_page() {
     return theme(‘blog_help’);
}

In this hook example, we define each menu item in each $item array and the path is defined in the ‘admin/addbloghelp’ part.

The ‘title’ and ‘description’ are the title and description of the page.

The ‘page callback’ tells what function is fired when the user lands on the page. In this example we set up a custom function below the hook that will load a theme file called ‘blog_help.tpl.php.’ Because we use the ‘theme’ function the ‘.tpl.php’ part of the file isn’t needed, as Drupal knows to look for files with that extension. In that template file we put the content that will be displayed on this page.

Finally ‘access arguments’ sets the access level for the page.

There are endless possibilities for using Drupal's hook system. I encourage you to visit Drupal.org to learn more about the Drupal hook system and everything Drupal.