[Drupal] How to create URL alias for custom menu / Implementation of hook_pathauto()?

| | 3 min read

This article is about creating URL alias for a custom menu that we created in our custom module. This was a requirement in one of my projects, to change the node id to node title in one of the custom created url. I was able to do this by implementing hook_pathauto. This is done on Drupal 7.

Note:
Pathauto is a module that helps you to automatically create URL/path aliases for almost every type of content. Please check this link to know more about pathauto

I'll demonstrate the process of creating URL alias for a custom menu with code. First I need to create a custom menu, for which we will create alias later. So for creating a custom menu, I'm going to implement the hook_menu().

function custom_menu()
 $items['test/%'] = array(
    'title' => 'My Page',
    'page callback' => 'custom_my_page_view',
    'page arguments' => array(1),
    'type' => MENU_CALLBACK,
  );
}

This is my menu hook implementation in which I have created a menu 'test/%'. '%' is supposed to be a node id, in my case. In the custom_my_page_view, I'm going to use the node corresponding to this node id.

Now, creating the URL alias for this menu. For this I need to implement the hook hook_pathauto().

You can see information regarding the variables that needs to be set during implementation of pathauto inside the 'API.txt' file inside the pathauto module' directory. So, please have a look at this file for a better understanding.

Ok, coming back to the implementation of pathauto hook, there is one variable passed as an argument in the hook_pathauto; $op. The value of $op will be always 'settings'. The pathauto hook should always return an object. There are some predefined object variables that needs to be set inside pathauto hook. Let us have a brief look into them.

  • module: It should be the name of the module in which you are implementing the pathauto hook.
  • groupheader: This is the label for the settings group.(displayed in admin/config/search/path/patterns).
  • patterndescr: This is the label for the default URL pattern.(displayed in admin/config/search/path/patterns).
  • patterndefault: This is the default URL pattern(displayed in admin/config/search/path/patterns).
  • token_type: The token type, can be node, user, term(denoting taxonomy term), etc.
  • patternitems: Used when we need to create multiple patterns in a module. This is done by assigning an array with a key- value pair, where the key is an identifier of each pattern and value denotes the pattern description.
  • bulkname: The label to be displayed for this module in the bulk update tab of URL aliases (displayed inside admin/config/search/path/update_bulk).
  • bulkdescr: Bulk update description.

And, now the code :

function custom_pathauto($op) {
  switch ($op) {
    case 'settings':
      $settings = array();
      $settings['module'] = 'custom';
      $settings['token_type'] = 'node';
      $settings['groupheader'] = t('Custom paths');
      $settings['patterndescr'] = t('Default pattern');
      $settings['patterndefault'] = 'test/[node:title]';
      $settings['patternitems'] = array('mypattern' => 'Extra patterns created for my module');
    return (object) $settings;
  }
}

So, this is the basic pathauto hook implementation. This alone will not create a URL alias. We need to call another function in pathauto, pathauto_create_alias(), at the time of creation/updation of a content to create the URL alias of that content. You can call this function inside hook_node_insert()/hook_node_update().

function custom_node_insert($node) {
  if ($node->type == 'story') {
    pathauto_create_alias('custom', $op, 'test/' . $node->nid , array('node' => $node), 'mypattern');
  }
}

Note the last parameter given to the pathauto_create_alias(). This is the additional pattern I have added in $settings['patternitems'] of pathauto hook implementation. If we are using the default pattern we can omit the last parameter.

Please click the link for information about pathauto_create_alias()

Suppose we have already a lot of nodes that were created already and need to create the new aliases for all of them, we need to bulk update all the nodes. For this we need to implement another hook hook_pathauto_bulkupdate(), which will connect to the bulk updation process. See a simple implementation of this hook below:

function custom_pathauto_bulkupdate() {
  $query = db_select('node', 'n');
  $query -> condition('n.type', 'story')
         ->fields('n', array('nid'));
  $results = $query->execute()->fetchCol();
  $count = 0;
  foreach($results as $nid) {
    $node = node_load($nid);
    custom_generate_alias($node, 'bulkupdate');
    $count++;
  }
  drupal_set_message($count . ' paths were updated.');
}

function custom_generate_alias($node, $op) {
  module_load_include('inc', 'pathauto');
  pathauto_create_alias('custom', $op, 'test/' . $node->nid , array('node' => $node), 'mypattern');
}

This is how I have created URL aliases for my custom menu. Hope this note saves your time.. :)