Creating Custom Menus in Drupal

Abbas Suterwala
Abbas Suterwala
Share

Drupal has a very customizable architecture so that you can extend Drupal to suit your needs. Drupal provides various kinds of hooks which a module can use to customize the functionality, and has a powerful menu system to create menu items in your Drupal site. Drupal also provides hooks for module developers to hook into the Drupal menu system and create menu items for the module to function. The menu system hooks in Drupal allow registering of URLs so that the module can define how the request to the URL will be handled and also if the module wants to add that link to the menu. In this article we are going to see how your module can hook into the Drupal menu system to register callbacks on URLs and how to add those in the navigation menu if needed.

Creating the module

Let’s start by creating a separate module called menudemo which we will use to demonstrate the various menu system functionalities that Drupal offers us. To create the menudemo module create a folder in menudemo sitesallmodulescustom  of your Drupal installation. In that folder create a file called menudemo.info with the following contents.
;$Id$
name = menudemo
description = A module to  demo drupals menu system
package = Menu Demo Package
core = 7.x
files[] = menudemo.module
The menudemo.info file describes our module to the Drupal system. In the info file we have described various parameters such as the name of the module, the description, the package name etc. Also in your menudemo folder create your menudemo.module file. Your folder structure will be as follows: menu structure Once you have added your files, you should be able to see your module in the Drupal module list. You should go and enable the module now as shown below. menu module

Responding to a URL via menu callback

Once we have created our module with the necessary files, let’s look at the hook Drupal provides to module developers as a way to hook into the Drupal menu system. For a module to hook into the Drupal menu system, one has to implement the hook_menu hook. This implementation of this hook is required to return an associative array of the menu items the module is suppose to add. The associative array will contain the paths of the menu as the key and its properties as the value of that array item. So, in our module we give the implementation of hook_menu by providing the function menudemo_menu as follows
/**

* Implementation of hook_menu().

*/

function menudemo_menu() {

    $menuitems['menudemo'] = array(

    'title' => 'My Menu',

    'page callback' => 'menudemo_mymenu_page_callback',

    'access callback' => TRUE,

    'type' => MENU_CALLBACK,

    );

    return $menuitems;

}

function menudemo_mymenu_page_callback() {

    return 'My Menu URL was hit';

}
In the function menudemo_menu
above we have created an associative array with the key as menudemo which is the name of our module. But you can use a key here based on the URL you want to handle and respond to in your module. Then we have passed the parameters defining the menu items such as its title. Defining the type as MENU_CALLBACK just means register a path which, when requested, will be able to handle the request. No new menu item will be created. And we have also defined the access callback and set it as TRUE so that this menu item can be accessed by everyone. We have defined the page callback in which you specify the function which should be called when this URL is accessed. We have defined it to menudemo_mymenu_page_callback. In the function menudemo_mymenu_page_callback we have just returned a string which we will display when our registered URL is requested. Now just go to the URL <your drupal installation URL>/menudemo
, if you have clean URLs enabled, or to <your drupal installation URL>/?q=menudemo if clean URLs are not enabled. You should be able to see the output of your page callback on the screen as follows Note: – Drupal caches the hooks which a module implements so you might have to go to Administration » Configuration » Development » Performance and do a clear cache to take into consideration the new changes in the hooks implemented by your module in Drupal 7. my menu 

Fetching the parameters from the menu URL

Drupal also lets you fetch parameters from the Drupal URL by passing it to your callback function. So, if you have registered for a URL path and there are values after it in the URL then those are passed as parameters to your callback function. This becomes very handy when you want the menu item to work differently based on the parameter passed to it. If, for instance, you wanted to add a menu item to process products on your site, you might have the same callback function cater to the different URL such as menudemo/product/add
or menudemo/product/view etc. To catch the parameters we will have to modify our callback as shown below
function menudemo_mymenu_page_callback($firstparameter = '', $secondparameter ='') {
    $result = 'My Menu URL was hit';
    $result.='<br> The first parameter passed to the url is :'.$firstparameter;
    $result.='<br> The second parameter passed to the url is :'.$secondparameter;
    return $result;
}
Here there are two parameters caught and passed to the callback function. Then in the callback function we are just displaying the parameters on the screen. So in case if you to the URL <your drupal installation URL>/menudemo/product/edit the output will be as follows your menu

Adding your menu links in the navigation bar

Up to now, we have seen how we can register URLs with the Drupal system so that any request to those URLs will be handled by our callback function. If we want that URL to show up in the navigation menu, we can do that by changing the type of the menu item. The modified menudemo_menu function is as follows
/**

* Implementation of hook_menu().

*/

function menudemo_menu() {

    $menuitems['menudemo'] = array(

    'title' => 'My Menu',

    'page callback' => 'menudemo_mymenu_page_callback',

    'access callback' => TRUE,

    'type' => MENU_NORMAL_ITEM,

    );

    return $menuitems;

}
In the above function we have passed the type as MENU_NORMAL_ITEM. This will make the menu item show up in the navigation menu as shown below. my menu url

Creating sub menu in the navigation bar

After you have created the item in the navigation menu, you might want to create submenus or nested menu items below it. We can add submenus to menu items by appending the submenu item path after the menu item path in the associative array we pass back in menudemo_menu function. To add the sub menu we will update the function menudemo_menu as follows
/**

* Implementation of hook_menu().

*/

function menudemo_menu() {

    $menuitems['menudemo'] = array(

    'title' => 'My Menu',

    'page callback' => 'menudemo_mymenu_page_callback',

    'access callback' => TRUE,

    'type' => MENU_NORMAL_ITEM,

    );

    $menuitems['menudemo/submenu'] = array(

    'title' => 'My Sub menu',

    'page callback' => 'menudemo_mysubmenu_page_callback',

    'access callback' => TRUE,

    'type' => MENU_NORMAL_ITEM,

    );

    return $menuitems;

}

function menudemo_mysubmenu_page_callback() {

    $result = 'My  Sub Menu URL was hit';

    return $result;

}
Here we have added one more entry in the associative array with the key as menudemo/submenu. This will create a submenu below the menudemo menu item. We have defined the function menudemo_mysubmenu_page_callback
as the callback function for the submenu item which just displays the text as 'My  Sub Menu URL was hit'. Now if we click on the submenu item, we will be able to see the output as follows my sub menu

Conclusion

The Drupal system lets the module developers plug into the Drupal main processing via Drupal hooks. In this article, we saw how we can use the hook_menu hook of the Drupal menu system to register our own callbacks to handle request to specific URLs or add menu items to the navigation menu. The Drupal system also passes the parameters in the URL to the callback function, which can help to write a generic callback function that could handle multiple tasks based on the parameters passed to it. Now, depending on the module you are trying to make in Drupal, you might want to add simple menu items or nested menu items to let the user easily access the functionality you are trying to provide. Have fun adding menus to your next Drupal module.

Frequently Asked Questions about Creating Custom Menus in Drupal

How can I create a custom menu in Drupal 7?

Creating a custom menu in Drupal 7 involves a few steps. First, navigate to the ‘Structure’ section in your Drupal dashboard and click on ‘Menus’. Then, click on ‘+ Add menu’. You’ll be prompted to give your new menu a title and a description. After filling in these details, click on ‘Save’. You can then add links to your new menu by clicking on ‘Add link’. Fill in the necessary details for each link and click ‘Save’ when you’re done.

What happened to hook_menu in Drupal 8?

In Drupal 8, hook_menu has been replaced by several new systems. The routing system now handles paths and their associated controllers, while menu links are now plugins. This change was made to improve flexibility and to decouple menu links from router items.

How can I convert my Drupal 7 module to Drupal 8?

Converting a Drupal 7 module to Drupal 8 involves several steps. First, you’ll need to replace hook_menu with a routing.yml file. Then, you’ll need to convert your menu links to plugins. You’ll also need to update your code to use the new Drupal 8 APIs.

How can I add a link to a custom menu in Drupal?

To add a link to a custom menu in Drupal, navigate to the ‘Structure’ section in your Drupal dashboard and click on ‘Menus’. Then, find the menu you want to add a link to and click on ‘Add link’. Fill in the necessary details for the link and click ‘Save’ when you’re done.

How can I manage menus in Drupal?

You can manage menus in Drupal through the ‘Structure’ section in your Drupal dashboard. Here, you can add new menus, add links to existing menus, and rearrange the order of links in a menu.

How can I create a dropdown menu in Drupal?

Creating a dropdown menu in Drupal involves adding a link to a menu and then adding child links to that link. The child links will appear as a dropdown menu when the parent link is hovered over.

How can I create a menu block in Drupal?

To create a menu block in Drupal, navigate to the ‘Structure’ section in your Drupal dashboard and click on ‘Block layout’. Then, click on ‘+ Add block’. You’ll be prompted to give your new block a title and a description. After filling in these details, select ‘Menu’ from the ‘Type’ dropdown and choose the menu you want to display in the block. Click ‘Save’ when you’re done.

How can I theme a menu in Drupal?

Theming a menu in Drupal involves creating a template file for the menu in your theme’s directory. The template file should be named ‘menu–menu-name.html.twig’, where ‘menu-name’ is the machine name of the menu. In this file, you can customize the HTML markup and CSS classes for the menu.

How can I translate a menu in Drupal?

To translate a menu in Drupal, you’ll need to enable the ‘Interface Translation’ and ‘Content Translation’ modules. Then, navigate to the ‘Structure’ section in your Drupal dashboard and click on ‘Menus’. Find the menu you want to translate and click on ‘Translate’. You can then add translations for each link in the menu.

How can I programmatically create a menu in Drupal?

To programmatically create a menu in Drupal, you’ll need to use the ‘MenuLinkDefault’ class. You can create a new instance of this class and set the properties for the menu link, such as the title, description, and path. Then, call the ‘save’ method to save the new menu link.