Avoid using WordPress and Apache disk_cache extension together … unless you understand what is going on and you now how to fix the problem.

Using both together led one of the sites I have worked on (http://www.gdium.com) to display RSS feeds instead of posts and pages. After a forced refresh of the page (CTRL+R in Firefox) the correct page was displayed. This have been driving me crazy for several days until I actually remembered I had enabled Apache disk caching for another website on the same server.

After disabling disk_cache I did a search and I found someone that was having the same problem which confirmed what I thought.

Today I have spent a few minutes trying to understand how Drupal renders a Not found page when accessing a node that does not exist. After going through the node.module code I couldn’t find anything.

This is one of the most frustrating things with Drupal, you need to know pretty well how it works internally to understand what is happening and where to look because there is some magic here and there.

It turns out that the menu system is one of the places where some of this magic is implemented to show a Not found page when an object cannot be retrieved from the database. Basically, the menu system implements a way for automatically load objects from the database to display or edit. If the object cannot be retrieved then you get the error. Let’s see how this works.

When you write a module you register the mapping between paths and function calls using the hook_menu function. For instance, for the node module you have

function node_module() {
  $items['node/%node'] = array(
    'title callback' => 'node_page_title',
    'title arguments' => array(1),
    'page callback' => 'node_page_view',
    'page arguments' => array(1),
    'access callback' => 'node_access',
    'access arguments' => array('view', 1),
    'type' => MENU_CALLBACK);

This is adding a mapping for the path node/%node to the node_page_view function. The arguments that are passed are defined by the array page_arguments. As you see the array contains one single element: 1.

1 relates to the position 1 in the array generated from the path. In our case:

  • 0 -> node,
  • 1-> %node

% is used as a wildcard, so it will match anything  (except special characters like / that is used as separator) after node/. When instead of  % you use %something some magic is performed: a call to something_load(%something) is performed. Imagine that you tap into the url http://www.example.com/node/45, then instead of passing 45 to the node_page_view function, it will pass node_load(45). Amazing, isn’t it? Furthermore, if node_load(45) fails to load an object from the database because there is no node with a nid (the primary key of the node table) of 45 a Not found page is returned. That is the kind of tricks that are difficult to spot but can increase productivity.

In case you need to pass other parameters to the something_load function, you can add a ‘load arguments’ entry to the hash for a path with the extra arguments to the load function as an array.

More information in the Drupal documentation.