A Very Quick Introduction to Drupal's hook_menu() and hook_theme()

Disclaimer: This post describes how to create custom pages on your drupal site, and create custom menu items (page routes), within a module. After reading this post, you will know how to implement hook_theme() and hook_menu() to create custom urls (Paths) and very basic content templates in both Drupal 6 and Drupal 7. This tutorial assumes you know how to create and upload files to your server using FTP, and also know how to create a basic custom module to use as a foundation. If you do not know how to create a basic custom module, check out our quick tutorial on the subject.

NOTE: For practice, we will be adding comments to almost all lines of code.

1. Creating a hook

Hooks in Drupal are just ways of modifying the website page's results.
Let's create one in our new module.

There are two hooks we will be using in this exercise: hook_menu and hook_theme. These links will take you to the drupal api pages that describe each hook.

New let's edit the custom_example.module, and make its contents the following: <?php /* * Implementation of hook_menu() */ function custom_example_menu(){ }

Now here is the important part about using a hook:
Copy the hook function from Drupal's API page, and replace the word hook with your module's name.
Your module is now "hook"ed into Drupal's menu system.

2. Creating a custom menu item

Edit the module file again to make its content the following: <?php /* * Implementation of hook_menu() */ function custom_example_menu(){ // path location (http://www.url.com/foo/bar ) $items['foo/bar'] = array( // page title 'title' => 'Page Title', // describe the page for the menu system. site visitors will not see this 'description' => 'Simple custom hook_menu() implementation.', // function that is called when visiting the new path 'page callback' => 'my_page_function', // permissions required to view page 'access arguments' => array('access content'), ); return $items; }

Save before continuing (always save your work!), and now let's look at what we've done here:

  • $items['foo/bar']: This key adds a new path to drupal at http://url.com/foo/bar - replace foo/bar with the preferred URL location.
  • 'title' => 'Page Title': This required key-value pair will create the page title of the menu item. Most themes implement the page title as an H1 html tag.
  • 'description' => 'Simple custom hook_menu() implementation.': This key-value pair is a short description of the purpose of this new path.
  • 'page callback' => 'my_page_function': This key-value pair is the name of the function that Drupal will call when a user is visiting the new path.
  • 'access arguments' => array('access content'): This key-value pair determines who can see the new path and content, by providing an array of specific permissions a user must have. Here is a reference page of permissions you may find useful.

If you visit the hook_menu api page, you will see that there are many more options available, but this is all we will need for this introductory tutorial.

Next, we need to create the callback function, since we named one up above. Add the following below your hook_menu function: <?php /* * Returns custom content to Drupal */ function my_page_function(){ }

We'll leave it empty for now and come back to it after the next section.

3. Creating a custom template file

We'll now create a custom template file in the module. Add the following to your custom_example.module: <?php /* * Implement hook_theme(). */ function custom_example_theme(){ return array( 'my_custom_template' => array( // file name will be custom-page.tpl.php 'template' => 'custom-page', ), ); }

We've now hooked our module into the theme system. Let's look at what these items do:

  • 'my_custom_template' => array(): This is the name of your template implementation.
  • 'template' => 'custom-page': This key-value pair will create a call to a new template file that will look like this: 'custom-page.tpl.php'. Note: You don't have to add '.tpl.php' to the value. Also, this file is not created yet, we will do that below.
  • That's it for this part, now let's look at how to make our custom page return this new template file. Edit your module again, find your my_page_function function, and alter it to look like the following: /* * Returns custom content to Drupal */ function my_page_function(){ // Call theme() function, so that Drupal includes the custom-page.tpl.php template return theme('my_custom_template'); }

    What we're doing here is telling Drupal, "When a site visitor goes to /foo/bar, include my custom template".

    Now the last thing you need to do is actually create that template. In the same directory as your module, create a new file titled 'custom-page.tpl.php'. Type the following (or anything you'd like) into it. Hello World That's pretty much it! Save the files, flush all your Drupal caches, and visit your new path. Here is what mine looks like:

    Below is a copy of the entire module file so that you can see it in it's final form. <?php /* * Implementation of hook_menu() */ function custom_example_menu(){ // path location (http://www.url.com/foo/bar ) $items['foo/bar'] = array( // page title 'title' => 'Page Title', // describe the page for the menu system. site visitors will not see this 'description' => 'Simple custom hook_menu() implementation.', // function that is called when visiting the new path 'page callback' => 'my_page_function', // permissions required to view page 'access arguments' => array('access content'), ); return $items; } /* * Returns custom content to Drupal */ function my_page_function(){ // Call theme() function, so that Drupal includes the custom-page.tpl.php template return theme('my_custom_template'); } /* * Implementation of hook_theme(). */ function custom_example_theme(){ return array( 'my_custom_template' => array( // template file name will be custom-page.tpl.php 'template' => 'custom-page', ), ); }

    That's the basics of hook_menu and hook_theme. Don't forget to enable your custom module in module administration. Good luck!

    References:

    1. Drupal 7 hook_menu API
    2. Drupal 7 hook_theme API
    3. Drupal 6 hook_menu API
    4. Drupal 6 hook_theme API
    5. A good reference post on hook_menu on drupal.org