Drupal coder

module development

How to define page callbacks that you don't want to render using page template in Drupal?

Defining custom pages in your Drupal module is easy using hook_menu and a callback function. Let's have a look at an example.

/**
 * Implementation of hook_menu().
 */
function my_module_menu() {
  $items['hello'] = array(
    'title' => 'Hello world',
    'page callback' => 'my_module_page',
    'access callback' => TRUE,
  );
}

function my_module_page() {
  return t('Hello world');
}

In this example, going to /hello will show you a page saying "hello world" rendered using your page template. So this page will display with your logo, blocks, footer, ...

In some cases you don't want this. Mostly in case you won't return HTML but something like XML, JSON, ... Let's have a look at two ways how this can be accomplished.

Additional processing in Drupal's Webform 3 module

Webform is one of the most popular and most useful Drupal modules. It allows you to build forms using the administration interface without any programming. It saves the submitted data to the database and you can optionally let the data be sent to one or multiple e-mail addresses. And if that's not enough, you can even do some additional processing yourself like saving the results to an external system (using an API), logging extra data, ... This is accomplished using the "Additional processing (and validation)" fields available when you are editing your form.

At least... This used to be possible. With the imminent release of Webform 3 (at the moment of this writing beta 4 is the latest release), this won't be possible anymore (out of the box).

But you still need this functionality in your project? Lets see what your options are.

How to debug outgoing mails in Drupal?

There are a few issues involved when you are developing a Drupal website that needs to send out mails. When you need to test the sending of these e-mails you might want to see the results instantly without waiting for the actual mail to be delivered or you might want to test the mail with multiple addresses (instead of always your own) but you might not want to send out the actual mail. And in some cases you might not even have access to a mail server in your development environment.

As always, there are a few options to solve these issues in Drupal.

Configure links on modules overview page in Drupal 7

One of the smaller improvements in Drupal 7 is the addition of "Configure" and "Permissions" for each module in the modules configuration page. For each module we now have quicklinks pointing to the module's configuration page and the correct section on the "permissions" page.

configure-link-drupal7.png

Since we're all working hard now on making our contributed modules Drupal 7 compatible, I wanted to mention here how to make use of this small feature in your own module.
The "permissions" link is added there automatically by Drupal. For the "Configure" link you need to add one more line to your module's info file.

January 18, 2010Drupal 7, Drupal, module development

Clear cache before running hook_boot for the first time

I've bumped my head over this one a few times now and I always tend to forget. If you're implementing hook_boot, the module cache (system table) needs to be rebuilt. You can do this by going to admin/build/module.

Why is this? hook_boot is called during the bootstrap like this:

/**
 * Call all init or exit hooks without including all modules.
 *
 * @param $hook
 *   The name of the bootstrap hook we wish to invoke.
 */
function bootstrap_invoke_all($hook) {
  foreach (module_list(TRUE, TRUE) as $module) {
    drupal_load('module', $module);
    module_invoke($module, $hook);
  }
}

As you can see, module_list is called here with the second parameter set to TRUE. Looking at what this parameter means, gives us $bootstrap. Let's look at the (partial) implementation of the module_list function to see what it's used for:

function module_list($refresh = FALSE, $bootstrap = TRUE, $sort = FALSE, $fixed_list = NULL) {
//...
      if ($bootstrap) {
        $result = db_query("SELECT name, filename, throttle FROM {system} WHERE type = 'module' AND status = 1 AND bootstrap = 1 ORDER BY weight ASC, filename ASC");
      }
//...      
}

We're filtering on bootstrap = 1 when selecting from the system table.

As you know or not know, this table only gets (re)built when the available modules are scanned. This happens when module_rebuild_cache is run. This is what gets done if you go to your modules page.

March 31, 2009Drupal, module development