background image

Content tagged with: menu callback

Eric's picture

When I'm coding modules, I rely heavily on the information found here: http://api.drupal.org/api/functions. Searching for functions can show you what already exists and how to use them in your code. Before you code something from scratch (or start to write your own SQL statement), you should start with the API. To be honest, I can't say that I've never coding something from scratch.

Another way to figure out how Drupal functionality is generated is to check out the menu hook in the module. A lot of helpful information resides here. For instance, you might want to embed a forum in a block or a custom module. If the functionality you're trying to recreate is found on your site at http://YOURSITE/forum, look for the menu_hook entry for "forum". Open /modules/forum/forum.module, locate the forum_menu() function, and look in the associative array for the "forum" entry:

// it starts with:
$items['forum'] = array(

In this case, the "page callback" property of the array tells you which callback function is being used. If you search the forum.module file, you notice that this function does not exist. The "file" property of the array tells you that this function requires an additional file to function properly, in this case "forum.pages.inc". At this point, it's helpful to review the code in the page callback function and use the online API documentation as a reference. NOTE: more information about hook_menu() can be found here: http://api.drupal.org/api/function/hook_menu/6.

For this example, I decided to use the forum_get_forum() function in my code. Before I can simply call this function, I must include the same file defined in the "file" property of the menu_hook entry:

<?php
require_once(drupal_get_path('module','forum') . '/forum.pages.inc');
$forums = forum_get_forums(0);
?>

Now, I have the html generated from the forum module. You could use this same process to recreate functionality from other modules as well.

Eric's picture

I recently was tasked with tracking when a user submitted a form, but in this case, the form was submitted to an external site. Normally, if the form was being submitted locally I could have added a form_alter hook function and modify the submit handlers. The following code snippet will explain how you can add a javascript submit event on the form, and using a synchronous AJAX call, execute server side code before the user leaves the site.

First, I setup a page callback used by the AJAX call to execute my inserted code.

<?php
// define the menu callback item
function MYMODULE_menu() {
 
$items = array();
   
 
$items[] = array(
   
'path' => 'MYAJAXPATH',
   
'title' => NULL,
   
'callback' => '_MYAJAXPATH_callback',
   
'access' => true,
   
'type' => MENU_CALLBACK,
  );
   
  return
$items;
}

// define the menu callback function
function _MYAJAXPATH_callback() {
 
// here, you could add any code you'd like (modify session data, execute some SQL, etc).
   
  // I added the die statement to prevent the theme layer from being executed
 
die;
}
?>

Make sure the page callback works by browsing to it. If you don't output any HTML in your callback function, you should just get a blank page.

Next, you'll need to attach a submit handler to the form and make the synchronous AJAX call.

<?php
$(document).ready(function(){
  $(
'form#FORM-ID-THAT-SUBMITS-EXTERNAL').submit(function(){
    $.
ajax({
     
type: "GET",
     
url: "/MYAJAXPATH",
     
cache: false,
     
async: false,
    });
  });
});
?>

I added a few properties to the AJAX request object to enable this functionality: cache set to false ensures the page request will not be pulled from your browser cache & async set to false will ensure the form is not submitted until the AJAX request is done. jQuery's default AJAX calls are set to asynchronous, which does not guarantee the request will be made before the form is submitted.